]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[CLEANUP] move remaining stats sockets code to dumpstats
authorWilly Tarreau <w@1wt.eu>
Sun, 16 Aug 2009 17:06:42 +0000 (19:06 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 16 Aug 2009 17:35:36 +0000 (19:35 +0200)
The remains of the stats socket code has nothing to do in proto_uxst
anymore and must move to dumpstats. The code is much cleaner and more
structured. It was also an opportunity to rename AN_REQ_UNIX_STATS
as AN_REQ_STATS_SOCK as the stats socket is no longer unix-specific
either.

The last item refering to stats in proto_uxst is the setting of the
task's nice value which should in fact come from the listener.

include/common/defaults.h
include/proto/dumpstats.h
include/types/buffers.h
src/dumpstats.c
src/proto_uxst.c
src/session.c

index f0873cfae48e13de5888baadff41388500822f3d..966ef4fbd9aece606f0bbf8ed239ce5166dc14b4 100644 (file)
@@ -64,8 +64,8 @@
 // max # args on a configuration line
 #define MAX_LINE_ARGS   64
 
-// max # args on a uxts socket
-#define MAX_UXST_ARGS   16
+// max # args on a stats socket
+#define MAX_STATS_ARGS  16
 
 // max # of added headers per request
 #define MAX_NEWHDR      10
index 844879ab2487f45381df3d30509a3d5557dbf43e..a0167a7f1f858630c3a8bdf27feb805f7b0cadfc 100644 (file)
@@ -44,6 +44,8 @@
 #define STATS_ST_REP   2
 #define STATS_ST_CLOSE 3
 
+int stats_sock_parse_request(struct session *s, char *line);
+int stats_sock_req_analyser(struct session *s, struct buffer *req, int an_bit);
 int stats_dump_raw(struct session *s, struct buffer *rep, struct uri_auth *uri);
 void stats_dump_raw_to_buffer(struct session *s, struct buffer *req);
 int stats_dump_http(struct session *s, struct buffer *rep, struct uri_auth *uri);
index 055311663fd91b4460b7a2beda6bf0031ad889b5..b9836b23ee3647d94fee6bab2d246f9eb1746cc8 100644 (file)
 #define AN_REQ_HTTP_INNER       0x00000020  /* inner processing of HTTP request */
 #define AN_REQ_HTTP_TARPIT      0x00000040  /* wait for end of HTTP tarpit */
 #define AN_REQ_HTTP_BODY        0x00000080  /* inspect HTTP request body */
-#define AN_REQ_UNIX_STATS       0x00000100  /* process unix stats socket request */
+#define AN_REQ_STATS_SOCK       0x00000100  /* process stats socket request */
 
 #define AN_RTR_HTTP_HDR         0x00000200  /* inspect HTTP response headers */
 #define AN_REQ_PRST_RDP_COOKIE  0x00000400  /* persistence on rdp cookie */
index 2683b52988d39de8be24ecfb0ac2b4e0394431e9..91c90e9226caed8f528a79028462b3278d7b1f40 100644 (file)
 #include <proto/stream_interface.h>
 #include <proto/task.h>
 
+const char stats_sock_usage_msg[] =
+        "Unknown command. Please enter one of the following commands only :\n"
+        "  show info   : report information about the running process\n"
+        "  show stat   : report counters for each proxy and server\n"
+        "  show errors : report last request and response errors for each proxy\n"
+        "  show sess   : report the list of current sessions\n"
+       "\n";
+
+const struct chunk stats_sock_usage = {
+        .str = (char *)&stats_sock_usage_msg,
+        .len = sizeof(stats_sock_usage_msg)-1
+};
+
 /* This function parses a "stats" statement in the "global" section. It returns
  * -1 if there is any error, otherwise zero. If it returns -1, it may write an
  * error message into ther <err> buffer, for at most <errlen> bytes, trailing
@@ -107,7 +120,7 @@ static int stats_parse_global(char **args, int section_type, struct proxy *curpx
                global.stats_sock.options = LI_O_NONE;
                global.stats_sock.accept = uxst_event_accept;
                global.stats_sock.handler = process_session;
-               global.stats_sock.analysers = AN_REQ_UNIX_STATS;
+               global.stats_sock.analysers = AN_REQ_STATS_SOCK;
                global.stats_sock.private = global.stats_fe; /* must point to the frontend */
 
                global.stats_fe->timeout.client = MS_TO_TICKS(10000); /* default timeout of 10 seconds */
@@ -211,6 +224,147 @@ int print_csv_header(struct chunk *msg, int size)
                            "\n");
 }
 
+/* Parses the request line in <cmd> and possibly starts dumping stats on
+ * s->rep with the hijack bit set. Returns 1 if OK, 0 in case of any error.
+ * The line is modified after parsing.
+ */
+int stats_sock_parse_request(struct session *s, char *line)
+{
+       char *args[MAX_STATS_ARGS + 1];
+       int arg;
+
+       while (isspace((unsigned char)*line))
+               line++;
+
+       arg = 0;
+       args[arg] = line;
+
+       while (*line && arg < MAX_STATS_ARGS) {
+               if (isspace((unsigned char)*line)) {
+                       *line++ = '\0';
+
+                       while (isspace((unsigned char)*line))
+                               line++;
+
+                       args[++arg] = line;
+                       continue;
+               }
+
+               line++;
+       }
+
+       while (++arg <= MAX_STATS_ARGS)
+               args[arg] = line;
+
+       if (strcmp(args[0], "show") == 0) {
+               if (strcmp(args[1], "stat") == 0) {
+                       if (*args[2] && *args[3] && *args[4]) {
+                               s->data_ctx.stats.flags |= STAT_BOUND;
+                               s->data_ctx.stats.iid   = atoi(args[2]);
+                               s->data_ctx.stats.type  = atoi(args[3]);
+                               s->data_ctx.stats.sid   = atoi(args[4]);
+                       }
+
+                       s->data_ctx.stats.flags |= STAT_SHOW_STAT;
+                       s->data_ctx.stats.flags |= STAT_FMT_CSV;
+                       s->ana_state = STATS_ST_REP;
+                       buffer_install_hijacker(s, s->rep, stats_dump_raw_to_buffer);
+               }
+               else if (strcmp(args[1], "info") == 0) {
+                       s->data_ctx.stats.flags |= STAT_SHOW_INFO;
+                       s->data_ctx.stats.flags |= STAT_FMT_CSV;
+                       s->ana_state = STATS_ST_REP;
+                       buffer_install_hijacker(s, s->rep, stats_dump_raw_to_buffer);
+               }
+               else if (strcmp(args[1], "sess") == 0) {
+                       s->ana_state = STATS_ST_REP;
+                       buffer_install_hijacker(s, s->rep, stats_dump_sess_to_buffer);
+               }
+               else if (strcmp(args[1], "errors") == 0) {
+                       if (*args[2])
+                               s->data_ctx.errors.iid  = atoi(args[2]);
+                       else
+                               s->data_ctx.errors.iid  = -1;
+                       s->data_ctx.errors.px = NULL;
+                       s->ana_state = STATS_ST_REP;
+                       buffer_install_hijacker(s, s->rep, stats_dump_errors_to_buffer);
+               }
+               else { /* neither "stat" nor "info" nor "sess" */
+                       return 0;
+               }
+       }
+       else { /* not "show" */
+               return 0;
+       }
+       return 1;
+}
+
+/* Processes the stats interpreter on the statistics socket.
+ * In order to ease the transition, we simply simulate the server status
+ * for now. It only knows states STATS_ST_INIT, STATS_ST_REQ, STATS_ST_REP, and
+ * STATS_ST_CLOSE. It removes its analyser bit from req->analysers once done.
+ * It always returns 0.
+ */
+int stats_sock_req_analyser(struct session *s, struct buffer *req, int an_bit)
+{
+       char *line, *p;
+
+       switch (s->ana_state) {
+       case STATS_ST_INIT:
+               /* Stats output not initialized yet */
+               memset(&s->data_ctx.stats, 0, sizeof(s->data_ctx.stats));
+               s->data_source = DATA_SRC_STATS;
+               s->ana_state = STATS_ST_REQ;
+               buffer_write_dis(s->req);
+               /* fall through */
+
+       case STATS_ST_REQ:
+               /* Now, stats are initialized, hijack is not set, and
+                * we are waiting for a complete request line.
+                */
+
+               line = s->req->data;
+               p = memchr(line, '\n', s->req->l);
+
+               if (p) {
+                       *p = '\0';
+                       if (!stats_sock_parse_request(s, line)) {
+                               /* invalid request */
+                               stream_int_retnclose(s->req->prod, &stats_sock_usage);
+                               s->ana_state = 0;
+                               req->analysers = 0;
+                               return 0;
+                       }
+               }
+
+               /* processing a valid or incomplete request */
+               if ((req->flags & BF_FULL)                    || /* invalid request */
+                   (req->flags & BF_READ_ERROR)              || /* input error */
+                   (req->flags & BF_READ_TIMEOUT)            || /* read timeout */
+                   tick_is_expired(req->analyse_exp, now_ms) || /* request timeout */
+                   (req->flags & BF_SHUTR)) {                   /* input closed */
+                       buffer_shutw_now(s->rep);
+                       s->ana_state = 0;
+                       req->analysers = 0;
+                       return 0;
+               }
+               /* don't forward nor abort */
+               req->flags |= BF_READ_DONTWAIT; /* we plan to read small requests */
+               return 0;
+
+       case STATS_ST_REP:
+               /* do nothing while response is being processed */
+               return 0;
+
+       case STATS_ST_CLOSE:
+               /* end of dump */
+               s->req->analysers &= ~an_bit;
+               s->ana_state = 0;
+               break;
+       }
+       return 0;
+}
+
 /*
  * Produces statistics data for the session <s>. Expects to be called with
  * client socket shut down on input. It *may* make use of informations from
index 1c751d65345976f1d822eb40136cf1b3a396c70a..5078369798655dea7a2b30b745eb0ecc543b336b 100644 (file)
@@ -41,7 +41,6 @@
 #include <proto/acl.h>
 #include <proto/backend.h>
 #include <proto/buffers.h>
-#include <proto/dumpstats.h>
 #include <proto/fd.h>
 #include <proto/log.h>
 #include <proto/protocols.h>
@@ -78,19 +77,6 @@ static struct protocol proto_unix = {
        .nb_listeners = 0,
 };
 
-const char unix_sock_usage_msg[] =
-        "Unknown command. Please enter one of the following commands only :\n"
-        "  show info   : report information about the running process\n"
-        "  show stat   : report counters for each proxy and server\n"
-        "  show errors : report last request and response errors for each proxy\n"
-        "  show sess   : report the list of current sessions\n"
-       "\n";
-
-const struct chunk unix_sock_usage = {
-        .str = (char *)&unix_sock_usage_msg,
-        .len = sizeof(unix_sock_usage_msg)-1
-};
-
 /********************************
  * 1) low-level socket functions
  ********************************/
@@ -572,148 +558,6 @@ int uxst_event_accept(int fd) {
        return 0;
 }
 
-/* Parses the request line in <cmd> and possibly starts dumping stats on
- * s->rep with the hijack bit set. Returns 1 if OK, 0 in case of any error.
- * The line is modified after parsing.
- */
-int unix_sock_parse_request(struct session *s, char *line)
-{
-       char *args[MAX_UXST_ARGS + 1];
-       int arg;
-
-       while (isspace((unsigned char)*line))
-               line++;
-
-       arg = 0;
-       args[arg] = line;
-
-       while (*line && arg < MAX_UXST_ARGS) {
-               if (isspace((unsigned char)*line)) {
-                       *line++ = '\0';
-
-                       while (isspace((unsigned char)*line))
-                               line++;
-
-                       args[++arg] = line;
-                       continue;
-               }
-
-               line++;
-       }
-
-       while (++arg <= MAX_UXST_ARGS)
-               args[arg] = line;
-
-       if (strcmp(args[0], "show") == 0) {
-               if (strcmp(args[1], "stat") == 0) {
-                       if (*args[2] && *args[3] && *args[4]) {
-                               s->data_ctx.stats.flags |= STAT_BOUND;
-                               s->data_ctx.stats.iid   = atoi(args[2]);
-                               s->data_ctx.stats.type  = atoi(args[3]);
-                               s->data_ctx.stats.sid   = atoi(args[4]);
-                       }
-
-                       s->data_ctx.stats.flags |= STAT_SHOW_STAT;
-                       s->data_ctx.stats.flags |= STAT_FMT_CSV;
-                       s->ana_state = STATS_ST_REP;
-                       buffer_install_hijacker(s, s->rep, stats_dump_raw_to_buffer);
-               }
-               else if (strcmp(args[1], "info") == 0) {
-                       s->data_ctx.stats.flags |= STAT_SHOW_INFO;
-                       s->data_ctx.stats.flags |= STAT_FMT_CSV;
-                       s->ana_state = STATS_ST_REP;
-                       buffer_install_hijacker(s, s->rep, stats_dump_raw_to_buffer);
-               }
-               else if (strcmp(args[1], "sess") == 0) {
-                       s->ana_state = STATS_ST_REP;
-                       buffer_install_hijacker(s, s->rep, stats_dump_sess_to_buffer);
-               }
-               else if (strcmp(args[1], "errors") == 0) {
-                       if (*args[2])
-                               s->data_ctx.errors.iid  = atoi(args[2]);
-                       else
-                               s->data_ctx.errors.iid  = -1;
-                       s->data_ctx.errors.px = NULL;
-                       s->ana_state = STATS_ST_REP;
-                       buffer_install_hijacker(s, s->rep, stats_dump_errors_to_buffer);
-               }
-               else { /* neither "stat" nor "info" nor "sess" */
-                       return 0;
-               }
-       }
-       else { /* not "show" */
-               return 0;
-       }
-       return 1;
-}
-
-/* Processes the stats interpreter on the statistics socket.
- * In order to ease the transition, we simply simulate the server status
- * for now. It only knows states STATS_ST_INIT, STATS_ST_REQ, STATS_ST_REP, and
- * STATS_ST_CLOSE. It removes the AN_REQ_UNIX_STATS bit from req->analysers
- * once done. It always returns 0.
- */
-int uxst_req_analyser_stats(struct session *s, struct buffer *req, int an_bit)
-{
-       char *line, *p;
-
-       switch (s->ana_state) {
-       case STATS_ST_INIT:
-               /* Stats output not initialized yet */
-               memset(&s->data_ctx.stats, 0, sizeof(s->data_ctx.stats));
-               s->data_source = DATA_SRC_STATS;
-               s->ana_state = STATS_ST_REQ;
-               buffer_write_dis(s->req);
-               /* fall through */
-
-       case STATS_ST_REQ:
-               /* Now, stats are initialized, hijack is not set, and
-                * we are waiting for a complete request line.
-                */
-
-               line = s->req->data;
-               p = memchr(line, '\n', s->req->l);
-
-               if (p) {
-                       *p = '\0';
-                       if (!unix_sock_parse_request(s, line)) {
-                               /* invalid request */
-                               stream_int_retnclose(s->req->prod, &unix_sock_usage);
-                               s->ana_state = 0;
-                               req->analysers = 0;
-                               return 0;
-                       }
-               }
-
-               /* processing a valid or incomplete request */
-               if ((req->flags & BF_FULL)                    || /* invalid request */
-                   (req->flags & BF_READ_ERROR)              || /* input error */
-                   (req->flags & BF_READ_TIMEOUT)            || /* read timeout */
-                   tick_is_expired(req->analyse_exp, now_ms) || /* request timeout */
-                   (req->flags & BF_SHUTR)) {                   /* input closed */
-                       buffer_shutw_now(s->rep);
-                       s->ana_state = 0;
-                       req->analysers = 0;
-                       return 0;
-               }
-               /* don't forward nor abort */
-               req->flags |= BF_READ_DONTWAIT; /* we plan to read small requests */
-               return 0;
-
-       case STATS_ST_REP:
-               /* do nothing while response is being processed */
-               return 0;
-
-       case STATS_ST_CLOSE:
-               /* end of dump */
-               s->req->analysers &= ~an_bit;
-               s->ana_state = 0;
-               break;
-       }
-       return 0;
-}
-
-
 __attribute__((constructor))
 static void __uxst_protocol_init(void)
 {
index 56bf102e376722c2ecf1de51e95f18d5d5cf1cfa..809ee2bd10530b6ba3d940376e4199834885f09f 100644 (file)
 #include <proto/acl.h>
 #include <proto/backend.h>
 #include <proto/buffers.h>
+#include <proto/dumpstats.h>
 #include <proto/hdr_idx.h>
 #include <proto/log.h>
 #include <proto/session.h>
 #include <proto/pipe.h>
 #include <proto/proto_http.h>
 #include <proto/proto_tcp.h>
-#include <proto/proto_uxst.h>
 #include <proto/proxy.h>
 #include <proto/queue.h>
 #include <proto/server.h>
@@ -841,9 +841,9 @@ resync_stream_interface:
                                                break;
                                }
 
-                               if (s->req->analysers & AN_REQ_UNIX_STATS) {
-                                       last_ana |= AN_REQ_UNIX_STATS;
-                                       if (!uxst_req_analyser_stats(s, s->req, AN_REQ_UNIX_STATS))
+                               if (s->req->analysers & AN_REQ_STATS_SOCK) {
+                                       last_ana |= AN_REQ_STATS_SOCK;
+                                       if (!stats_sock_req_analyser(s, s->req, AN_REQ_STATS_SOCK))
                                                break;
                                }