]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
stats: support per thread stats in json output
authorVictor Julien <victor@inliniac.net>
Tue, 26 May 2015 10:00:36 +0000 (12:00 +0200)
committerVictor Julien <victor@inliniac.net>
Wed, 27 May 2015 12:14:45 +0000 (14:14 +0200)
Default is only to output totals. Optionally per thread can be added.

Both can be enabled together.

src/output-json-stats.c
suricata.yaml.in

index 63e11a7784fe0e76d89df1bdb3cf2a2b6485b5c1..1b684c99b92320e16127464cfd3b7bfee90540c6 100644 (file)
@@ -51,6 +51,9 @@
 #ifdef HAVE_LIBJANSSON
 #include <jansson.h>
 
+#define JSON_STATS_TOTALS  (1<<0)
+#define JSON_STATS_THREADS (1<<1)
+
 typedef struct OutputStatsCtx_ {
     LogFileCtx *file_ctx;
     uint32_t flags; /** Store mode */
@@ -127,17 +130,43 @@ static int JsonStatsLogger(ThreadVars *tv, void *thread_data, const StatsTable *
     json_object_set_new(js_stats, "uptime", json_string(uptime));
 
     uint32_t u = 0;
-    for (u = 0; u < st->nstats; u++) {
-        if (st->stats[u].name == NULL)
-            break;
-        char str[256];
-        snprintf(str, sizeof(str), "%s.%s", st->stats[u].tm_name, st->stats[u].name);
-        json_t *js_type = OutputStats2Json(js_stats, str);
-
-        if (js_type != NULL) {
-            json_object_set_new(js_type, &str[rindex(str, '.')-str+1], json_integer(st->stats[u].value));
+    if (aft->statslog_ctx->flags & JSON_STATS_TOTALS) {
+        for (u = 0; u < st->nstats; u++) {
+            if (st->stats[u].name == NULL)
+                continue;
+            char str[256];
+            snprintf(str, sizeof(str), "%s.%s", st->stats[u].tm_name, st->stats[u].name);
+            json_t *js_type = OutputStats2Json(js_stats, str);
+            if (js_type != NULL) {
+                json_object_set_new(js_type, &str[rindex(str, '.')-str+1],
+                                    json_integer(st->stats[u].value));
+            }
+        }
+    }
+
+    /* per thread stats */
+    if (st->tstats != NULL && (aft->statslog_ctx->flags & JSON_STATS_THREADS)) {
+        /* for each thread (store) */
+        uint32_t x;
+        for (x = 0; x < st->ntstats; x++) {
+            uint32_t offset = x * st->nstats;
+
+            /* for each counter */
+            for (u = offset; u < (offset + st->nstats); u++) {
+                if (st->tstats[u].name == NULL)
+                    continue;
+
+                char str[256];
+                snprintf(str, sizeof(str), "%s.%s", st->tstats[u].tm_name, st->tstats[u].name);
+                json_t *js_type = OutputStats2Json(js_stats, str);
+
+                if (js_type != NULL) {
+                    json_object_set_new(js_type, &str[rindex(str, '.')-str+1], json_integer(st->tstats[u].value));
+                }
+            }
         }
     }
+
     json_object_set_new(js, "stats", js_stats);
 
     OutputJSONBuffer(js, aft->statslog_ctx->file_ctx, buffer);
@@ -224,6 +253,21 @@ OutputCtx *OutputStatsLogInit(ConfNode *conf)
         LogFileFreeCtx(file_ctx);
         return NULL;
     }
+    stats_ctx->flags = JSON_STATS_TOTALS;
+
+    if (conf != NULL) {
+        const char *totals = ConfNodeLookupChildValue(conf, "totals");
+        const char *threads = ConfNodeLookupChildValue(conf, "threads");
+        SCLogDebug("totals %s threads %s", totals, threads);
+
+        if (totals != NULL && ConfValIsFalse(totals)) {
+            stats_ctx->flags &= ~JSON_STATS_TOTALS;
+        }
+        if (threads != NULL && ConfValIsTrue(threads)) {
+            stats_ctx->flags |= JSON_STATS_THREADS;
+        }
+        SCLogDebug("stats_ctx->flags %08x", stats_ctx->flags);
+    }
 
     OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
     if (unlikely(output_ctx == NULL)) {
@@ -255,6 +299,22 @@ OutputCtx *OutputStatsLogInitSub(ConfNode *conf, OutputCtx *parent_ctx)
     if (unlikely(stats_ctx == NULL))
         return NULL;
 
+    stats_ctx->flags = JSON_STATS_TOTALS;
+
+    if (conf != NULL) {
+        const char *totals = ConfNodeLookupChildValue(conf, "totals");
+        const char *threads = ConfNodeLookupChildValue(conf, "threads");
+        SCLogDebug("totals %s threads %s", totals, threads);
+
+        if (totals != NULL && ConfValIsFalse(totals)) {
+            stats_ctx->flags &= ~JSON_STATS_TOTALS;
+        }
+        if (threads != NULL && ConfValIsTrue(threads)) {
+            stats_ctx->flags |= JSON_STATS_THREADS;
+        }
+        SCLogDebug("stats_ctx->flags %08x", stats_ctx->flags);
+    }
+
     OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
     if (unlikely(output_ctx == NULL)) {
         SCFree(stats_ctx);
index 147e002d65dda8128e4ea2cf18fb7287e2a5ec94..f2e9a18533565469af5c20c34c94e5c65cd923cb 100644 (file)
@@ -140,7 +140,9 @@ outputs:
         #    alerts: no       # log alerts that caused drops
         - smtp
         - ssh
-        - stats
+        - stats:
+            totals: yes       # stats for all threads merged together
+            threads: no       # per thread stats
         # bi-directional flows
         #- flow
         # uni-directional flows