From: Willy Tarreau Date: Mon, 26 Aug 2019 16:17:04 +0000 (+0200) Subject: MINOR: sink: implement "show events" to show supported sinks and dump the rings X-Git-Tag: v2.1-dev2~161 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9f830d7408cbfe2100a575e3cf2de5233a2ce80f;p=thirdparty%2Fhaproxy.git MINOR: sink: implement "show events" to show supported sinks and dump the rings The new "show events" CLI keyword lists supported event sinks. When passed a buffer-type sink it completely dumps it. no drops at all during attachment even at 8 millon evts/s. still missing the attachment limit though. --- diff --git a/doc/management.txt b/doc/management.txt index b54b30c5bb..8b3f6f6138 100644 --- a/doc/management.txt +++ b/doc/management.txt @@ -1964,6 +1964,11 @@ show errors [|] [request|response] is the slash ('/') in header name "header/bizarre", which is not a valid HTTP character for a header name. +show events [] + With no option, this lists all known event sinks and their types. With an + option, it will dump all available events in the designated sink if it is of + type buffer. + show fd [] Dump the list of either all open file descriptors or just the one number if specified. This is only aimed at developers who need to observe internal diff --git a/src/sink.c b/src/sink.c index 3295cca021..5746c4bc2d 100644 --- a/src/sink.c +++ b/src/sink.c @@ -24,9 +24,11 @@ #include #include #include +#include #include #include #include +#include struct list sink_list = LIST_HEAD_INIT(sink_list); @@ -176,6 +178,42 @@ void sink_write(struct sink *sink, const struct ist msg[], size_t nmsg) HA_ATOMIC_ADD(&sink->ctx.dropped, 1); } +/* parse the "show events" command, returns 1 if a message is returned, otherwise zero */ +static int cli_parse_show_events(char **args, char *payload, struct appctx *appctx, void *private) +{ + struct sink *sink; + + args++; // make args[1] the 1st arg + + if (!*args[1]) { + /* no arg => report the list of supported sink */ + chunk_printf(&trash, "Supported events sinks:\n"); + list_for_each_entry(sink, &sink_list, sink_list) { + chunk_appendf(&trash, " %-10s : type=%s, %u dropped, %s\n", + sink->name, + sink->type == SINK_TYPE_NEW ? "init" : + sink->type == SINK_TYPE_FD ? "fd" : + sink->type == SINK_TYPE_BUFFER ? "buffer" : "?", + sink->ctx.dropped, sink->desc); + } + + trash.area[trash.data] = 0; + return cli_msg(appctx, LOG_WARNING, trash.area); + } + + if (!cli_has_level(appctx, ACCESS_LVL_OPER)) + return 1; + + sink = sink_find(args[1]); + if (!sink) + return cli_err(appctx, "No such event sink"); + + if (sink->type != SINK_TYPE_BUFFER) + return cli_msg(appctx, LOG_NOTICE, "Nothing to report for this sink"); + + return ring_attach_cli(sink->ctx.ring, appctx); +} + static void sink_init() { sink_new_fd("stdout", "standard output (fd#1)", SINK_FMT_RAW, 1); @@ -198,6 +236,13 @@ static void sink_deinit() INITCALL0(STG_REGISTER, sink_init); REGISTER_POST_DEINIT(sink_deinit); +static struct cli_kw_list cli_kws = {{ },{ + { { "show", "events", NULL }, "show events [] : show event sink state", cli_parse_show_events, cli_io_handler_show_ring, cli_io_release_show_ring }, + {{},} +}}; + +INITCALL1(STG_REGISTER, cli_register_kw, &cli_kws); + /* * Local variables: * c-indent-level: 8