MINOR: sink: create definitions a minimal code for event sinks
The principle will be to be able to dispatch events to various destinations
called "sinks". This is already done in part in logs where log servers can
be either a UDP socket or a file descriptor. This will be needed with the
new trace subsystem where we may also want to add ring buffers. And it turns
out that all such destinations make sense at all places. Logs may need to be
sent to a TCP server via a ring buffer, or consulted from the CLI. Trace
events may need to be sent to stdout/stderr as well as to remote log servers.
This patch creates a new structure "sink" aiming at addressing these similar
needs. The goal is to merge together what is common to all of them, such as
the output format, the dropped events count, etc, and also keep separately
the target identification (network address, file descriptor). Provisions
were made to have a "waiter" on the sink. For a TCP log server it will be
the task to wake up after writing to the log buffer. For a ring buffer, it
could be the list of watchers on the CLI running a "tail" operation and
waiting for new events. A lock was also placed in the struct since many
operations will require some locking, including the FD ones. The output
formats covers those in use by logs and two extra ones prepending the ISO
time in front of the message (convenient for stdio/buffer).
For now only the generic infrastructure is present, no type-specific
output is implemented. There's the sink_write() function which prepares
and formats a message to be sent, trying hard to avoid copies and only
using pointer manipulation, where the type-specific code just has to be
added. Dropped messages are already counted (for now 100% drop). The
message is put into an iovec array as it will be trivial to use with
file descriptors and sockets.
2019-08-11 14:38:56 +00:00
|
|
|
/*
|
|
|
|
* include/proto/sink.h
|
|
|
|
* This file provides declarations for event sinks management
|
|
|
|
*
|
|
|
|
* Copyright (C) 2000-2019 Willy Tarreau - w@1wt.eu
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation, version 2.1
|
|
|
|
* exclusively.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _PROTO_SINK_H
|
|
|
|
#define _PROTO_SINK_H
|
|
|
|
|
|
|
|
#include <common/mini-clist.h>
|
|
|
|
#include <types/sink.h>
|
|
|
|
|
|
|
|
extern struct list sink_list;
|
|
|
|
|
|
|
|
struct sink *sink_find(const char *name);
|
2019-08-20 09:57:52 +00:00
|
|
|
struct sink *sink_new_fd(const char *name, const char *desc, enum sink_fmt fmt, int fd);
|
2019-08-27 14:41:06 +00:00
|
|
|
ssize_t __sink_write(struct sink *sink, const struct ist msg[], size_t nmsg);
|
|
|
|
int sink_announce_dropped(struct sink *sink);
|
|
|
|
|
|
|
|
|
|
|
|
/* tries to send <nmsg> message parts (up to 8, ignored above) from message
|
|
|
|
* array <msg> to sink <sink>. Formating according to the sink's preference is
|
|
|
|
* done here. Lost messages are accounted for in the sink's counter. If there
|
|
|
|
* were lost messages, an attempt is first made to indicate it.
|
|
|
|
*/
|
|
|
|
static inline void sink_write(struct sink *sink, const struct ist msg[], size_t nmsg)
|
|
|
|
{
|
|
|
|
ssize_t sent;
|
|
|
|
|
|
|
|
if (unlikely(sink->ctx.dropped > 0)) {
|
|
|
|
/* We need to take an exclusive lock so that other producers
|
|
|
|
* don't do the same thing at the same time and above all we
|
|
|
|
* want to be sure others have finished sending their messages
|
|
|
|
* so that the dropped event arrives exactly at the right
|
|
|
|
* position.
|
|
|
|
*/
|
|
|
|
HA_RWLOCK_WRLOCK(LOGSRV_LOCK, &sink->ctx.lock);
|
|
|
|
sent = sink_announce_dropped(sink);
|
|
|
|
HA_RWLOCK_WRUNLOCK(LOGSRV_LOCK, &sink->ctx.lock);
|
|
|
|
|
|
|
|
if (!sent) {
|
|
|
|
/* we failed, we don't try to send our log as if it
|
|
|
|
* would pass by chance, we'd get disordered events.
|
|
|
|
*/
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
HA_RWLOCK_RDLOCK(LOGSRV_LOCK, &sink->ctx.lock);
|
|
|
|
sent = __sink_write(sink, msg, nmsg);
|
|
|
|
HA_RWLOCK_RDUNLOCK(LOGSRV_LOCK, &sink->ctx.lock);
|
|
|
|
|
|
|
|
fail:
|
|
|
|
if (unlikely(sent <= 0))
|
|
|
|
HA_ATOMIC_ADD(&sink->ctx.dropped, 1);
|
|
|
|
}
|
MINOR: sink: create definitions a minimal code for event sinks
The principle will be to be able to dispatch events to various destinations
called "sinks". This is already done in part in logs where log servers can
be either a UDP socket or a file descriptor. This will be needed with the
new trace subsystem where we may also want to add ring buffers. And it turns
out that all such destinations make sense at all places. Logs may need to be
sent to a TCP server via a ring buffer, or consulted from the CLI. Trace
events may need to be sent to stdout/stderr as well as to remote log servers.
This patch creates a new structure "sink" aiming at addressing these similar
needs. The goal is to merge together what is common to all of them, such as
the output format, the dropped events count, etc, and also keep separately
the target identification (network address, file descriptor). Provisions
were made to have a "waiter" on the sink. For a TCP log server it will be
the task to wake up after writing to the log buffer. For a ring buffer, it
could be the list of watchers on the CLI running a "tail" operation and
waiting for new events. A lock was also placed in the struct since many
operations will require some locking, including the FD ones. The output
formats covers those in use by logs and two extra ones prepending the ISO
time in front of the message (convenient for stdio/buffer).
For now only the generic infrastructure is present, no type-specific
output is implemented. There's the sink_write() function which prepares
and formats a message to be sent, trying hard to avoid copies and only
using pointer manipulation, where the type-specific code just has to be
added. Dropped messages are already counted (for now 100% drop). The
message is put into an iovec array as it will be trivial to use with
file descriptors and sockets.
2019-08-11 14:38:56 +00:00
|
|
|
|
|
|
|
#endif /* _PROTO_SINK_H */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Local variables:
|
|
|
|
* c-indent-level: 8
|
|
|
|
* c-basic-offset: 8
|
|
|
|
* End:
|
|
|
|
*/
|