76 static char profiling_file_name[PATH_MAX] =
"";
77 static const char *profiling_file_mode =
"a";
78 static int profiling_rule_json = 0;
93 static int profiling_rules_sort_orders[8] = {
106 static uint32_t profiling_rules_limit = UINT32_MAX;
110 #define SET_ONE(x) { \
111 profiling_rules_sort_orders[0] = (x); \
112 profiling_rules_sort_orders[1] = -1; \
125 if (strcmp(val,
"ticks") == 0) {
128 else if (strcmp(val,
"avgticks") == 0) {
131 else if (strcmp(val,
"avgticks_match") == 0) {
134 else if (strcmp(val,
"avgticks_no_match") == 0) {
137 else if (strcmp(val,
"checks") == 0) {
140 else if (strcmp(val,
"matches") == 0) {
143 else if (strcmp(val,
"maxticks") == 0) {
147 SCLogError(
"Invalid profiling sort order: %s", val);
155 (uint16_t)strlen(val), val) <= 0) {
161 if (filename != NULL) {
166 snprintf(profiling_file_name,
sizeof(profiling_file_name),
167 "%s/%s", log_dir, filename);
171 profiling_file_mode =
"a";
173 profiling_file_mode =
"w";
179 profiling_rule_json = 1;
190 SCProfileSummarySortByTicks(
const void *a,
const void *b)
204 SCProfileSummarySortByAvgTicksMatch(
const void *a,
const void *b)
218 SCProfileSummarySortByAvgTicksNoMatch(
const void *a,
const void *b)
232 SCProfileSummarySortByAvgTicks(
const void *a,
const void *b)
246 SCProfileSummarySortByChecks(
const void *a,
const void *b)
260 SCProfileSummarySortByMatches(
const void *a,
const void *b)
274 SCProfileSummarySortByMaxTicks(
const void *a,
const void *b)
281 return s0->
max > s1->
max ? -1 : 1;
285 uint32_t count, uint64_t total_ticks,
286 const char *sort_desc)
292 json_t *js = json_object();
295 json_t *jsa = json_array();
301 gettimeofday(&tval, NULL);
303 json_object_set_new(js,
"timestamp", json_string(timebuf));
304 json_object_set_new(js,
"sort", json_string(sort_desc));
306 for (i = 0; i <
MIN(count, profiling_rules_limit); i++) {
310 if (summary[i].checks == 0)
313 json_t *jsm = json_object();
315 json_object_set_new(jsm,
"signature_id", json_integer(summary[i].sid));
316 json_object_set_new(jsm,
"gid", json_integer(summary[i].gid));
317 json_object_set_new(jsm,
"rev", json_integer(summary[i].rev));
319 json_object_set_new(jsm,
"checks", json_integer(summary[i].checks));
320 json_object_set_new(jsm,
"matches", json_integer(summary[i].matches));
322 json_object_set_new(jsm,
"ticks_total", json_integer(summary[i].ticks));
323 json_object_set_new(jsm,
"ticks_max", json_integer(summary[i].max));
324 json_object_set_new(jsm,
"ticks_avg", json_integer(summary[i].avgticks));
325 json_object_set_new(jsm,
"ticks_avg_match", json_integer(summary[i].avgticks_match));
326 json_object_set_new(jsm,
"ticks_avg_nomatch", json_integer(summary[i].avgticks_no_match));
328 double percent = (
long double)summary[i].ticks /
329 (
long double)total_ticks * 100;
330 json_object_set_new(jsm,
"percent", json_integer(percent));
331 json_array_append_new(jsa, jsm);
334 json_object_set_new(js,
"rules", jsa);
336 char *js_s = json_dumps(js,
337 JSON_PRESERVE_ORDER|JSON_COMPACT|JSON_ENSURE_ASCII|
342 fprintf(fp,
"%s\n", js_s);
348 uint32_t count, uint64_t total_ticks,
349 const char *sort_desc)
354 gettimeofday(&tval, NULL);
358 fprintf(fp,
" ----------------------------------------------"
359 "----------------------------\n");
360 fprintf(fp,
" Date: %" PRId32
"/%" PRId32
"/%04d -- "
361 "%02d:%02d:%02d.", tms->tm_mon + 1, tms->tm_mday, tms->tm_year + 1900,
362 tms->tm_hour,tms->tm_min, tms->tm_sec);
363 fprintf(fp,
" Sorted by: %s.\n", sort_desc);
364 fprintf(fp,
" ----------------------------------------------"
365 "----------------------------\n");
366 fprintf(fp,
" %-8s %-12s %-8s %-8s %-12s %-6s %-8s %-8s %-11s %-11s %-11s %-11s\n",
"Num",
"Rule",
"Gid",
"Rev",
"Ticks",
"%",
"Checks",
"Matches",
"Max Ticks",
"Avg Ticks",
"Avg Match",
"Avg No Match");
367 fprintf(fp,
" -------- "
380 for (i = 0; i <
MIN(count, profiling_rules_limit); i++) {
385 if (summary[i].checks == 0)
388 double percent = (
long double)summary[i].ticks /
389 (
long double)total_ticks * 100;
391 " %-8"PRIu32
" %-12u %-8"PRIu32
" %-8"PRIu32
" %-12"PRIu64
" %-6.2f %-8"PRIu64
" %-8"PRIu64
" %-11"PRIu64
" %-11.2f %-11.2f %-11.2f\n",
402 summary[i].avgticks_match,
403 summary[i].avgticks_no_match);
420 if (rules_ctx == NULL)
424 fp = fopen(profiling_file_name, profiling_file_mode);
427 SCLogError(
"failed to open %s: %s", profiling_file_name, strerror(errno));
437 SCLogError(
"Error allocating memory for profiling summary");
441 uint32_t count = rules_ctx->
size;
442 uint64_t total_ticks = 0;
444 SCLogPerf(
"Dumping profiling data for %u rules.", count);
446 memset(summary, 0, summary_size);
447 for (i = 0; i < count; i++) {
455 if (summary[i].ticks > 0) {
456 summary[i].
avgticks = (
long double)summary[i].ticks / (
long double)summary[i].
checks;
463 if (summary[i].ticks_match > 0) {
465 (
long double)summary[i].
matches;
468 if (summary[i].ticks_no_match > 0) {
470 ((
long double)summary[i].
checks - (
long double)summary[i].matches);
472 total_ticks += summary[i].
ticks;
475 int *order = profiling_rules_sort_orders;
476 while (*order != -1) {
477 const char *sort_desc = NULL;
481 SCProfileSummarySortByTicks);
486 SCProfileSummarySortByAvgTicks);
487 sort_desc =
"average ticks";
491 SCProfileSummarySortByChecks);
492 sort_desc =
"number of checks";
496 SCProfileSummarySortByMatches);
497 sort_desc =
"number of matches";
501 SCProfileSummarySortByMaxTicks);
502 sort_desc =
"max ticks";
506 SCProfileSummarySortByAvgTicksMatch);
507 sort_desc =
"average ticks (match)";
511 SCProfileSummarySortByAvgTicksNoMatch);
512 sort_desc =
"average ticks (no match)";
515 if (profiling_rule_json) {
516 DumpJson(fp, summary, count, total_ticks, sort_desc);
518 DumpText(fp, summary, count, total_ticks, sort_desc);
526 SCLogPerf(
"Done dumping profiling data.");
571 if (pthread_mutex_init(&ctx->
data_m, NULL) != 0) {
572 FatalError(
"Failed to initialize hash table mutex.");
582 SCProfilingRuleDump(ctx);
583 if (ctx->
data != NULL)
585 pthread_mutex_destroy(&ctx->
data_m);
592 if (ctx == NULL|| ctx->
size == 0)
627 SCProfilingRuleThreadMerge(det_ctx->
de_ctx, det_ctx);
651 while (sig != NULL) {
663 while (sig != NULL) {
671 SCLogPerf(
"Registered %"PRIu32
" rule profiling counters.", count);