]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MINOR] Allow listing of stick table by key
authorSimon Horman <horms@verge.net.au>
Wed, 15 Jun 2011 06:18:47 +0000 (15:18 +0900)
committerWilly Tarreau <w@1wt.eu>
Fri, 17 Jun 2011 09:39:29 +0000 (11:39 +0200)
doc/configuration.txt
src/dumpstats.c

index dde0c5411c67adb0825319dd8b5396f70a088bc1..a21c43a9e10e81f946cd3dba86c4ccfd4f7f6a3f 100644 (file)
@@ -9519,15 +9519,18 @@ show table
     >>> # table: front_pub, type: 0, size:204800, used:171454
     >>> # table: back_rdp, type: 0, size:204800, used:0
 
-show table <name> [ data.<type> <operator> <value> ]
+show table <name> [ data.<type> <operator> <value> ] | [ key <key> ]
   Dump contents of stick-table <name>. In this mode, a first line of generic
   information about the table is reported as with "show table", then all
   entries are dumped. Since this can be quite heavy, it is possible to specify
-  a filter in order to specify what entries to display. The filter then applies
-  to the stored data (see "stick-table" in section 4.2). One stored data type
-  has to be specified in <type>, and this data type must be stored in the table
-  otherwise an error is reported. The data is compared according to <operator>
-  with the 64-bit integer <value>. Operators are the same as with the ACLs :
+  a filter in order to specify what entries to display.
+
+  When the "data." form is used the filter applies to the stored data (see
+  "stick-table" in section 4.2).  A stored data type must be specified
+  in <type>, and this data type must be stored in the table otherwise an
+  error is reported. The data is compared according to <operator> with the
+  64-bit integer <value>.  Operators are the same as with the ACLs :
+
     - eq : match entries whose data is equal to this value
     - ne : match entries whose data is not equal to this value
     - le : match entries whose data is less than or equal to this value
@@ -9535,6 +9538,11 @@ show table <name> [ data.<type> <operator> <value> ]
     - lt : match entries whose data is less than this value
     - gt : match entries whose data is greater than this value
 
+  When the key form is used the filter applies to the key of
+  the stick table entry (see "stick-table" in section 4.2).
+  The stick table must be of type ip otherwise an error will
+  be reported.
+
   Example :
         $ echo "show table http_proxy" | socat stdio /tmp/sock1
     >>> # table: http_proxy, type: 0, size:204800, used:2
@@ -9551,6 +9559,12 @@ show table <name> [ data.<type> <operator> <value> ]
         $ echo "show table http_proxy data.conn_rate gt 5" | \
             socat stdio /tmp/sock1
     >>> # table: http_proxy, type: 0, size:204800, used:2
+    >>> 0x80e6a80: key=127.0.0.2 use=0 exp=3594740 gpc0=1 conn_rate(30000)=10 \
+          bytes_out_rate(60000)=191
+
+        $ echo "show table http_proxy key 127.0.0.2" | \
+            socat stdio /tmp/sock1
+    >>> # table: http_proxy, type: 0, size:204800, used:2
     >>> 0x80e6a80: key=127.0.0.2 use=0 exp=3594740 gpc0=1 conn_rate(30000)=10 \
           bytes_out_rate(60000)=191
 
index e99153a85e6226c6e118acbd595fcc18bd575888..bc1c2a4c2c4fd0fdb3361c6adc22dca650a7c5be 100644 (file)
@@ -14,6 +14,7 @@
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -504,7 +505,7 @@ static int stats_dump_table_entry_to_buffer(struct chunk *msg, struct stream_int
        return 1;
 }
 
-static void stats_sock_table_key_request(struct stream_interface *si, char **args)
+static void stats_sock_table_key_request(struct stream_interface *si, char **args, bool show)
 {
        struct session *s = si->applet.private;
        struct proxy *px;
@@ -542,7 +543,10 @@ static void stats_sock_table_key_request(struct stream_interface *si, char **arg
                static_table_key.key = (void *)&ip_key;
        }
        else {
-               si->applet.ctx.cli.msg = "Removing keys from non-ip tables is not supported\n";
+               if (show)
+                       si->applet.ctx.cli.msg = "Showing keys from non-ip tables is not supported\n";
+               else
+                       si->applet.ctx.cli.msg = "Removing keys from non-ip tables is not supported\n";
                si->applet.st0 = STAT_CLI_PRINT;
                return;
        }
@@ -555,11 +559,19 @@ static void stats_sock_table_key_request(struct stream_interface *si, char **arg
        }
 
        ts = stktable_lookup_key(&px->table, &static_table_key);
-       if (!ts) {
-               /* silent return, entry was already removed */
+       if (!ts)
+               return;
+
+       if (show) {
+               struct chunk msg;
+               chunk_init(&msg, trash, sizeof(trash));
+               if (!stats_dump_table_head_to_buffer(&msg, si, px, px))
+                       return;
+               stats_dump_table_entry_to_buffer(&msg, si, px, ts);
                return;
        }
-       else if (ts->ref_cnt) {
+
+       if (ts->ref_cnt) {
                /* don't delete an entry which is currently referenced */
                si->applet.ctx.cli.msg = "Entry currently in use, cannot remove\n";
                si->applet.st0 = STAT_CLI_PRINT;
@@ -655,6 +667,12 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line)
                        si->applet.st0 = STAT_CLI_O_ERR; // stats_dump_errors_to_buffer
                }
                else if (strcmp(args[1], "table") == 0) {
+                       if (*args[2] && *args[3] && strcmp(args[3], "key") == 0) {
+                               stats_sock_table_key_request(si, args, true);
+                               /* end of processing */
+                               return 1;
+                       }
+
                        si->applet.state = STAT_ST_INIT;
                        if (*args[2]) {
                                si->applet.ctx.table.target = find_stktable(args[2]);
@@ -697,7 +715,7 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line)
                                }
                        }
                        else if (*args[3]) {
-                               si->applet.ctx.cli.msg = "Optional argument only supports \"data.<store_data_type>\" <operator> <value>\n";
+                               si->applet.ctx.cli.msg = "Optional argument only supports \"data.<store_data_type>\" <operator> <value> and key <key>\n";
                                si->applet.st0 = STAT_CLI_PRINT;
                                return 1;
                        }
@@ -768,7 +786,7 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line)
                        return 1;
                }
                else if (strcmp(args[1], "table") == 0) {
-                       stats_sock_table_key_request(si, args);
+                       stats_sock_table_key_request(si, args, false);
                        /* end of processing */
                        return 1;
                }