]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
unix socket: add 'dump-counters' command
authorEric Leblond <eric@regit.org>
Wed, 5 Dec 2012 17:30:41 +0000 (18:30 +0100)
committerVictor Julien <victor@inliniac.net>
Tue, 26 Feb 2013 11:32:48 +0000 (12:32 +0100)
This patch adds a 'dump-counters' command which answer an output of
all performance counter.

src/counters.c
src/counters.h
src/unix-manager.c

index eb0287646d02a70aa5908ace9bcbff7ddce30abd..64d42251fd3e5aa0dba8ed3d03a2dcb1b1c14d95 100644 (file)
@@ -34,6 +34,7 @@
 #include "util-debug.h"
 #include "util-privs.h"
 #include "util-signal.h"
+#include "unix-manager.h"
 
 /** \todo Get the default log directory from some global resource. */
 #define SC_PERF_DEFAULT_LOG_FILENAME "stats.log"
@@ -1196,6 +1197,202 @@ static int SCPerfOutputCounterFileIface()
     return 1;
 }
 
+#ifdef BUILD_UNIX_SOCKET
+/**
+ * \brief The file output interface for the Perf Counter api
+ */
+TmEcode SCPerfOutputCounterSocket(json_t *cmd,
+                               json_t *answer, void *data)
+{
+    ThreadVars *tv = NULL;
+    SCPerfClubTMInst *pctmi = NULL;
+    SCPerfCounter *pc = NULL;
+    SCPerfCounter **pc_heads = NULL;
+
+    uint64_t ui64_temp = 0;
+    uint64_t ui64_result = 0;
+
+    double double_temp = 0;
+    double double_result = 0;
+
+    uint32_t u = 0;
+    int flag = 0;
+
+    if (sc_perf_op_ctx == NULL) {
+        json_object_set_new(answer, "message",
+                json_string("No performance counter context"));
+        return TM_ECODE_FAILED;
+    }
+
+    if (sc_perf_op_ctx->club_tm == 0) {
+        json_t *tm_array;
+
+        tm_array = json_object();
+        if (tm_array == NULL) {
+            json_object_set_new(answer, "message",
+                    json_string("internal error at json object creation"));
+            return TM_ECODE_FAILED;
+        }
+
+
+        for (u = 0; u < TVT_MAX; u++) {
+            tv = tv_root[u];
+            //if (pc_heads == NULL || pc_heads[u] == NULL)
+            //    continue;
+
+
+            while (tv != NULL) {
+                SCMutexLock(&tv->sc_perf_pctx.m);
+                pc = tv->sc_perf_pctx.head;
+                json_t *jdata;
+                int filled = 0;
+                jdata = json_object();
+                if (jdata == NULL) {
+                    json_decref(tm_array);
+                    json_object_set_new(answer, "message",
+                            json_string("internal error at json object creation"));
+                    SCMutexUnlock(&tv->sc_perf_pctx.m);
+                    return TM_ECODE_FAILED;
+                }
+
+                while (pc != NULL) {
+                    if (pc->disp == 0 || pc->value == NULL) {
+                        pc = pc->next;
+                        continue;
+                    }
+
+                    switch (pc->value->type) {
+                        case SC_PERF_TYPE_UINT64:
+                            SCPerfOutputCalculateCounterValue(pc,
+                                    &ui64_temp);
+                            json_object_set_new(jdata, pc->name->cname, json_integer(ui64_temp));
+                            filled = 1;
+                            break;
+                        case SC_PERF_TYPE_DOUBLE:
+                            SCPerfOutputCalculateCounterValue(pc,
+                                    &double_temp);
+                            json_object_set_new(jdata, pc->name->cname, json_real(double_temp));
+                            filled = 1;
+                            break;
+                    }
+                    pc = pc->next;
+                }
+
+                SCMutexUnlock(&tv->sc_perf_pctx.m);
+                if (filled == 1) {
+                    json_object_set_new(tm_array, pc->name->tm_name, jdata);
+                }
+                tv = tv->next;
+            }
+        }
+
+        json_object_set_new(answer, "message", tm_array);
+        return TM_ECODE_OK;
+    }
+
+    json_t *tm_array;
+
+    tm_array = json_object();
+    if (tm_array == NULL) {
+        json_object_set_new(answer, "message",
+                json_string("internal error at json object creation"));
+        return TM_ECODE_FAILED;
+    }
+
+    pctmi = sc_perf_op_ctx->pctmi;
+    while (pctmi != NULL) {
+        json_t *jdata;
+        int filled = 0;
+        jdata = json_object();
+        if (jdata == NULL) {
+            json_decref(tm_array);
+            json_object_set_new(answer, "message",
+                    json_string("internal error at json object creation"));
+            return TM_ECODE_FAILED;
+        }
+        if ((pc_heads = SCMalloc(pctmi->size * sizeof(SCPerfCounter *))) == NULL) {
+            json_decref(tm_array);
+            json_object_set_new(answer, "message",
+                    json_string("internal memory error"));
+            return TM_ECODE_FAILED;
+        }
+        memset(pc_heads, 0, pctmi->size * sizeof(SCPerfCounter *));
+
+        for (u = 0; u < pctmi->size; u++) {
+            pc_heads[u] = pctmi->head[u]->head;
+
+            SCMutexLock(&pctmi->head[u]->m);
+
+            while(pc_heads[u] != NULL && strcmp(pctmi->tm_name, pc_heads[u]->name->tm_name)) {
+                pc_heads[u] = pc_heads[u]->next;
+            }
+        }
+
+        flag = 1;
+        while(flag) {
+            ui64_result = 0;
+            double_result = 0;
+            if (pc_heads[0] == NULL)
+                break;
+            pc = pc_heads[0];
+
+            for (u = 0; u < pctmi->size; u++) {
+                switch (pc->value->type) {
+                    case SC_PERF_TYPE_UINT64:
+                        SCPerfOutputCalculateCounterValue(pc_heads[u], &ui64_temp);
+                        ui64_result += ui64_temp;
+
+                        break;
+                    case SC_PERF_TYPE_DOUBLE:
+                        SCPerfOutputCalculateCounterValue(pc_heads[u], &double_temp);
+                        double_result += double_temp;
+
+                        break;
+                }
+
+                if (pc_heads[u] != NULL)
+                    pc_heads[u] = pc_heads[u]->next;
+
+                if (pc_heads[u] == NULL ||
+                    (pc_heads[0] != NULL &&
+                        strcmp(pctmi->tm_name, pc_heads[0]->name->tm_name))) {
+                    flag = 0;
+                }
+            }
+
+            if (pc->disp == 0 || pc->value == NULL)
+                continue;
+
+            switch (pc->value->type) {
+                case SC_PERF_TYPE_UINT64:
+                    filled = 1;
+                    json_object_set_new(jdata, pc->name->cname, json_integer(ui64_result));
+                    break;
+                case SC_PERF_TYPE_DOUBLE:
+                    filled = 1;
+                    json_object_set_new(jdata, pc->name->cname, json_real(double_result));
+                    break;
+            }
+        }
+
+        for (u = 0; u < pctmi->size; u++)
+            SCMutexUnlock(&pctmi->head[u]->m);
+        if (filled == 1) {
+            json_object_set_new(tm_array, pctmi->tm_name, jdata);
+        }
+        pctmi = pctmi->next;
+
+        SCFree(pc_heads);
+
+    }
+
+    json_object_set_new(answer, "message", tm_array);
+
+    return TM_ECODE_OK;
+}
+
+#endif /* BUILD_UNIX_SOCKET */
+
 /**
  * \brief Initializes the perf counter api.  Things are hard coded currently.
  *        More work to be done when we implement multiple interfaces
index 2416453b24f1b1dea48c5f28bd81cf8b2d4d50fa..193ae465788f301b9f963365052a7fbff3f165e3 100644 (file)
@@ -269,4 +269,10 @@ void SCPerfCounterAddDouble(uint16_t, SCPerfCounterArray *, double);
         }                                                               \
     } while (0)
 
+#ifdef BUILD_UNIX_SOCKET
+#include <jansson.h>
+TmEcode SCPerfOutputCounterSocket(json_t *cmd,
+                               json_t *answer, void *data);
+#endif
+
 #endif /* __COUNTERS_H__ */
index e0d9348518de9eec49bb55cd6ac3a61538cd10c8..adc5539c0f4d22f8ef7dc7c4761b0cff1fe839a4 100644 (file)
@@ -851,6 +851,7 @@ void *UnixManagerThread(void *td)
     UnixManagerRegisterCommand("running-mode", UnixManagerRunningModeCommand, &command, 0);
     UnixManagerRegisterCommand("capture-mode", UnixManagerCaptureModeCommand, &command, 0);
     UnixManagerRegisterCommand("conf-get", UnixManagerConfGetCommand, &command, UNIX_CMD_TAKE_ARGS);
+    UnixManagerRegisterCommand("dump-counters", SCPerfOutputCounterSocket, NULL, 0);
 #if 0
     UnixManagerRegisterCommand("reload-rules", UnixManagerReloadRules, NULL, 0);
 #endif