profiling: add 'ruleset-profile' unix command

This patch adds a new unix command that allows the user to trigger
a dump of the ruleset profile to the file without having to stop
Suricata.

This will be really useful to debug performance issue related to
signatures in production environment.
pull/8879/head
Eric Leblond 3 years ago committed by Victor Julien
parent 020cfbcd61
commit 75b46edd79

@ -512,6 +512,7 @@ static void *StatsWakeupThread(void *arg)
/* assuming the assignment of an int to be atomic, and even if it's
* not, it should be okay */
tv->perf_public_ctx.perf_flag = 1;
tv->profile_flag = 1;
if (tv->inq != NULL) {
PacketQueue *q = tv->inq->pq;
@ -532,6 +533,7 @@ static void *StatsWakeupThread(void *arg)
/* assuming the assignment of an int to be atomic, and even if it's
* not, it should be okay */
tv->perf_public_ctx.perf_flag = 1;
tv->profile_flag = 1;
tv = tv->next;
}

@ -614,6 +614,14 @@ housekeeping:
/* process local work queue */
FlowWorkerProcessLocalFlows(tv, fw, p);
#ifdef PROFILE_RULES
/* aggregate statistics */
if (tv->profile_flag == 1) {
SCProfilingRuleThreatAggregate((DetectEngineThreadCtx *)detect_thread);
tv->profile_flag = 0;
}
#endif
return TM_ECODE_OK;
}

@ -127,6 +127,9 @@ typedef struct ThreadVars_ {
/** public counter store: counter syncs update this */
StatsPublicThreadContext perf_public_ctx;
/** profile sync needed */
uint32_t profile_flag;
/* mutex and condition used by management threads */
SCCtrlMutex *ctrl_mutex;

@ -40,6 +40,7 @@
#include "util-signal.h"
#include "util-buffer.h"
#include "util-path.h"
#include "util-profiling.h"
#if (defined BUILD_UNIX_SOCKET) && (defined HAVE_SYS_UN_H) && (defined HAVE_SYS_STAT_H) && (defined HAVE_SYS_TYPES_H)
#include <sys/un.h>
@ -779,6 +780,19 @@ static TmEcode UnixManagerRulesetStatsCommand(json_t *cmd,
SCReturnInt(retval);
}
#ifdef PROFILE_RULES
static TmEcode UnixManagerRulesetProfileCommand(json_t *cmd, json_t *server_msg, void *data)
{
SCEnter();
TmEcode retval;
DetectEngineCtx *de_ctx = DetectEngineGetCurrent();
retval = SCProfileRuleTriggerDump(de_ctx);
json_object_set_new(server_msg, "message", json_string("OK"));
SCReturnInt(retval);
}
#endif
static TmEcode UnixManagerShowFailedRules(json_t *cmd,
json_t *server_msg, void *data)
{
@ -1055,6 +1069,9 @@ int UnixManagerInit(void)
UnixManagerRegisterCommand("ruleset-reload-time", UnixManagerReloadTimeCommand, NULL, 0);
UnixManagerRegisterCommand("ruleset-stats", UnixManagerRulesetStatsCommand, NULL, 0);
UnixManagerRegisterCommand("ruleset-failed-rules", UnixManagerShowFailedRules, NULL, 0);
#ifdef PROFILE_RULES
UnixManagerRegisterCommand("ruleset-profile", UnixManagerRulesetProfileCommand, NULL, 0);
#endif
UnixManagerRegisterCommand("register-tenant-handler", UnixSocketRegisterTenantHandler, &command, UNIX_CMD_TAKE_ARGS);
UnixManagerRegisterCommand("unregister-tenant-handler", UnixSocketUnregisterTenantHandler, &command, UNIX_CMD_TAKE_ARGS);
UnixManagerRegisterCommand("register-tenant", UnixSocketRegisterTenant, &command, UNIX_CMD_TAKE_ARGS);

@ -581,10 +581,11 @@ void SCProfilingRuleThreadSetup(SCProfileDetectCtx *ctx, DetectEngineThreadCtx *
}
}
static void SCProfilingRuleThreadMerge(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx)
static void SCProfilingRuleThreadMerge(
DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, int reset)
{
if (de_ctx == NULL || de_ctx->profile_ctx == NULL || de_ctx->profile_ctx->data == NULL ||
det_ctx == NULL || det_ctx->rule_perf_data == NULL)
det_ctx == NULL || det_ctx->rule_perf_data == NULL)
return;
int i;
@ -593,6 +594,12 @@ static void SCProfilingRuleThreadMerge(DetectEngineCtx *de_ctx, DetectEngineThre
de_ctx->profile_ctx->data[i].matches += det_ctx->rule_perf_data[i].matches;
de_ctx->profile_ctx->data[i].ticks_match += det_ctx->rule_perf_data[i].ticks_match;
de_ctx->profile_ctx->data[i].ticks_no_match += det_ctx->rule_perf_data[i].ticks_no_match;
if (reset) {
det_ctx->rule_perf_data[i].checks = 0;
det_ctx->rule_perf_data[i].matches = 0;
det_ctx->rule_perf_data[i].ticks_match = 0;
det_ctx->rule_perf_data[i].ticks_no_match = 0;
}
if (det_ctx->rule_perf_data[i].max > de_ctx->profile_ctx->data[i].max)
de_ctx->profile_ctx->data[i].max = det_ctx->rule_perf_data[i].max;
}
@ -604,7 +611,7 @@ void SCProfilingRuleThreadCleanup(DetectEngineThreadCtx *det_ctx)
return;
pthread_mutex_lock(&det_ctx->de_ctx->profile_ctx->data_m);
SCProfilingRuleThreadMerge(det_ctx->de_ctx, det_ctx);
SCProfilingRuleThreadMerge(det_ctx->de_ctx, det_ctx, 0);
pthread_mutex_unlock(&det_ctx->de_ctx->profile_ctx->data_m);
SCFree(det_ctx->rule_perf_data);
@ -612,6 +619,16 @@ void SCProfilingRuleThreadCleanup(DetectEngineThreadCtx *det_ctx)
det_ctx->rule_perf_data_size = 0;
}
void SCProfilingRuleThreatAggregate(DetectEngineThreadCtx *det_ctx)
{
if (det_ctx == NULL || det_ctx->de_ctx == NULL || det_ctx->de_ctx->profile_ctx == NULL)
return;
pthread_mutex_lock(&det_ctx->de_ctx->profile_ctx->data_m);
SCProfilingRuleThreadMerge(det_ctx->de_ctx, det_ctx, 1);
pthread_mutex_unlock(&det_ctx->de_ctx->profile_ctx->data_m);
}
/**
* \brief Register the rule profiling counters.
*
@ -651,5 +668,11 @@ SCProfilingRuleInitCounters(DetectEngineCtx *de_ctx)
SCLogPerf("Registered %"PRIu32" rule profiling counters.", count);
}
int SCProfileRuleTriggerDump(DetectEngineCtx *de_ctx)
{
SCProfilingRuleDump(de_ctx->profile_ctx);
return TM_ECODE_OK;
}
#endif /* PROFILING */

Loading…
Cancel
Save