- pidfile
- presetenv
- resetenv
+ - ring
- uid
- ulimit-n
- user
next line in the configuration file sees the new environment. See also
"setenv", "presetenv", and "unsetenv".
+ring <name> [desc <desc>] [format <format>] [size <size>] [maxlen <length>]
+ Creates a named ring buffer which could be used on log line for instance.
+
+ <desc> is an optionnal description string of the ring. It will appear on
+ CLI. By default, <name> is reused to fill this field.
+
+ <format> is the log format used when generating syslog messages. It may be
+ one of the following :
+
+ iso A message containing only the ISO date, followed by the text.
+ The PID, process name and system name are omitted. This is
+ designed to be used with a local log server.
+
+ raw A message containing only the text. The level, PID, date, time,
+ process name and system name are omitted. This is designed to be
+ used in containers or during development, where the severity only
+ depends on the file descriptor used (stdout/stderr). This is
+ the default.
+
+ rfc3164 The RFC3164 syslog message format. This is the default.
+ (https://tools.ietf.org/html/rfc3164)
+
+ rfc5424 The RFC5424 syslog message format.
+ (https://tools.ietf.org/html/rfc5424)
+
+ short A message containing only a level between angle brackets such as
+ '<3>', followed by the text. The PID, date, time, process name
+ and system name are omitted. This is designed to be used with a
+ local log server. This format is compatible with what the systemd
+ logger consumes.
+
+ timed A message containing only a level between angle brackets such as
+ '<3>', followed by ISO date and by the text. The PID, process
+ name and system name are omitted. This is designed to be
+ used with a local log server.
+
+ <length> is the maximum length of an event message stored into the ring,
+ including formatted header. If an event message is longer than
+ <length>, it will be truncated to this length.
+
+ <name> is the ring identifier, which follows the same naming convention as
+ proxies and servers.
+
+ <size> is the optionnal size in bytes. Default value is set to BUFSIZE.
+
stats bind-process [ all | odd | even | <process_num>[-[process_num>]] ] ...
Limits the stats socket to a certain set of processes numbers. By default the
stats socket is bound to all processes, causing a warning to be emitted when
#include <common/mini-clist.h>
#include <proto/log.h>
+#include <proto/sink.h>
#include <proto/proxy.h>
/* configuration sections */
return sent;
}
+
+int parse_sinkbuf(char **args, char **err);
+
#endif /* _PROTO_SINK_H */
/*
/* describes the configuration and current state of an event sink */
struct sink {
struct list sink_list; // position in the sink list
- const char *name; // sink name
- const char *desc; // sink description
+ char *name; // sink name
+ char *desc; // sink description
enum sink_fmt fmt; // format expected by the sink
enum sink_type type; // type of storage
uint32_t maxlen; // max message length (truncated above)
free(global.log_send_hostname);
global.log_send_hostname = strdup(name);
}
+ else if (!strcmp(args[0], "ring")) {
+ if (!parse_sinkbuf(args, &errmsg)) {
+ ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ }
else if (!strcmp(args[0], "server-state-base")) { /* path base where HAProxy can find server state files */
if (global.server_state_base != NULL) {
ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
if (!sink)
goto end;
- sink->name = name;
- sink->desc = desc;
+ sink->name = strdup(name);
+ sink->desc = strdup(desc);
sink->fmt = fmt;
sink->type = SINK_TYPE_NEW;
sink->maxlen = BUFSIZE;
sink->ctx.ring = ring_new(size);
if (!sink->ctx.ring) {
LIST_DEL(&sink->sink_list);
+ free(sink->name);
+ free(sink->desc);
free(sink);
goto fail;
}
if (sink->type == SINK_TYPE_BUFFER)
ring_free(sink->ctx.ring);
LIST_DEL(&sink->sink_list);
+ free(sink->name);
+ free(sink->desc);
free(sink);
}
}
+/*
+ * Parse "ring" keyword and create corresponding sink buffer.
+ *
+ * The function returns 1 in success case, otherwise, it returns 0 and err is
+ * filled.
+ */
+
+int parse_sinkbuf(char **args, char **err)
+{
+ int myidx = 2;
+ size_t size = BUFSIZE;
+ size_t maxlen = size;
+ int format = SINK_FMT_RAW;
+ struct sink *sink = NULL;
+ char *desc, *name = args[1];
+ const char *inv;
+
+ if (!*name) {
+ memprintf(err, "missing sink name");
+ goto error;
+ }
+
+ inv = invalid_char(name);
+ if (inv) {
+ memprintf(err, "invalid sink name '%s' (character '%c' is not permitted)", name, *inv);
+ goto error;
+ }
+
+ desc = name;
+
+ while (*args[myidx]) {
+ if (!strcmp(args[myidx], "size")) {
+ myidx++;
+ size = atol(args[myidx]);
+ if (!size) {
+ memprintf(err, "invalid size '%s' for new sink buffer for ring '%s'", args[myidx], name);
+ goto error;
+ }
+ }
+ else if (!strcmp(args[myidx], "maxlen")) {
+ myidx++;
+ maxlen = atol(args[myidx]);
+ if (!maxlen) {
+ memprintf(err, "invalid size '%s' for new sink buffer for ring '%s'", args[myidx], name);
+ goto error;
+ }
+ }
+ else if (!strcmp(args[myidx], "maxlen")) {
+ myidx++;
+ maxlen = atol(args[myidx]);
+ if (!maxlen) {
+ memprintf(err, "invalid size '%s' for new sink buffer for ring '%s'", args[myidx], name);
+ goto error;
+ }
+ }
+ else if (!strcmp(args[myidx], "desc")) {
+ myidx++;
+ desc = args[myidx];
+ }
+ else if (!strcmp(args[myidx],"format")) {
+ myidx++;
+ if (!strcmp(args[myidx], "raw")) {
+ format = SINK_FMT_RAW;
+ }
+ else if (!strcmp(args[myidx], "short")) {
+ format = SINK_FMT_SHORT;
+ }
+ else if (!strcmp(args[myidx], "iso")) {
+ format = SINK_FMT_ISO;
+ }
+ else if (!strcmp(args[myidx], "timed")) {
+ format = SINK_FMT_TIMED;
+ }
+ else if (!strcmp(args[myidx], "rfc3164")) {
+ format = SINK_FMT_RFC3164;
+ }
+ else if (!strcmp(args[myidx], "rfc5424")) {
+ format = SINK_FMT_RFC5424;
+ }
+ else {
+ memprintf(err, "unknown format '%s' for new sink buffer for ring '%s'", args[myidx], name);
+ goto error;
+ }
+ }
+ else {
+ memprintf(err, "unknown parameter '%s' for new sink buffer for ring '%s'", args[myidx], name);
+ goto error;
+ }
+ myidx++;
+ }
+
+ if (maxlen > size) {
+ memprintf(err, "maxlen '%lu' exceeds size of the new sink buffer for ring '%s'", maxlen, name);
+ goto error;
+ }
+
+ sink = sink_new_buf(name, desc, format, size);
+ if (!sink || sink->type != SINK_TYPE_BUFFER) {
+ memprintf(err, "failed to create a new sink buffer for ring '%s'", name);
+ goto error;
+ }
+
+ sink->maxlen = maxlen;
+
+ return 1;
+error:
+ if (sink) {
+ if (sink->type == SINK_TYPE_BUFFER)
+ ring_free(sink->ctx.ring);
+ LIST_DEL(&sink->sink_list);
+ free(sink->name);
+ free(sink->desc);
+ free(sink);
+ }
+ return 0;
+
+}
+
INITCALL0(STG_REGISTER, sink_init);
REGISTER_POST_DEINIT(sink_deinit);