42
41
#define SC_PERF_PCRE_TIMEBASED_INTERVAL "^(?:(\\d+)([shm]))(?:(\\d+)([shm]))?(?:(\\d+)([shm]))?$"
44
43
static SCPerfOPIfaceContext *sc_perf_op_ctx = NULL;
44
static time_t sc_start_time;
45
/** refresh interval in seconds */
46
static uint32_t sc_counter_tts = SC_PERF_MGMTT_TTS;
47
/** is the stats counter enabled? */
48
static char sc_counter_enabled = TRUE;
49
/** append or overwrite? 1: append, 0: overwrite */
50
static char sc_counter_append = TRUE;
47
53
* \brief Adds a value of type uint64_t to the local counter.
263
269
* \retval An allocated string containing the log filename on success or NULL on
266
static char *SCPerfGetLogFilename(void)
272
static char *SCPerfGetLogFilename(ConfNode *stats)
268
274
char *log_dir = NULL;
269
275
char *log_filename = NULL;
276
const char* filename = NULL;
271
278
if (ConfGet("default-log-dir", &log_dir) != 1)
272
279
log_dir = DEFAULT_LOG_DIR;
286
filename = ConfNodeLookupChildValue(stats, "filename");
287
if (filename == NULL) {
288
filename = SC_PERF_DEFAULT_LOG_FILENAME;
291
filename = SC_PERF_DEFAULT_LOG_FILENAME;
278
294
if (snprintf(log_filename, PATH_MAX, "%s/%s", log_dir,
279
SC_PERF_DEFAULT_LOG_FILENAME) < 0) {
280
296
SCLogError(SC_ERR_SPRINTF, "Sprintf Error");
281
297
SCFree(log_filename);
313
ConfNode *root = ConfGetNode("outputs");
314
ConfNode *node = NULL;
315
ConfNode *stats = NULL;
317
TAILQ_FOREACH(node, &root->head, next) {
318
if (strncmp(node->val, "stats", 5) == 0) {
319
stats = node->head.tqh_first;
323
/* Check if the stats module is enabled or not */
325
const char *enabled = ConfNodeLookupChildValue(stats, "enabled");
326
if (enabled != NULL && ConfValIsFalse(enabled)) {
327
sc_counter_enabled = FALSE;
328
SCLogDebug("Stats module has been disabled");
331
const char *interval = ConfNodeLookupChildValue(stats, "interval");
332
if (interval != NULL)
333
sc_counter_tts = (uint32_t) atoi(interval);
335
const char *append = ConfNodeLookupChildValue(stats, "append");
337
sc_counter_append = ConfValIsTrue(append);
340
/* Store the engine start time */
341
time(&sc_start_time);
297
343
if ( (sc_perf_op_ctx = SCMalloc(sizeof(SCPerfOPIfaceContext))) == NULL) {
298
344
SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCPerfInitOPCtx. Exiting...");
299
345
exit(EXIT_FAILURE);
303
349
sc_perf_op_ctx->iface = SC_PERF_IFACE_FILE;
305
if ( (sc_perf_op_ctx->file = SCPerfGetLogFilename()) == NULL) {
351
if ( (sc_perf_op_ctx->file = SCPerfGetLogFilename(stats)) == NULL) {
306
352
SCLogInfo("Error retrieving Perf Counter API output file path");
309
if ( (sc_perf_op_ctx->fp = fopen(sc_perf_op_ctx->file, "w+")) == NULL) {
356
if (sc_counter_append)
361
if ( (sc_perf_op_ctx->fp = fopen(sc_perf_op_ctx->file, mode)) == NULL) {
310
362
SCLogError(SC_ERR_FOPEN, "fopen error opening file \"%s\". Resorting "
311
363
"to using the standard output for output",
312
364
sc_perf_op_ctx->file);
340
392
static void SCPerfReleaseOPCtx()
394
if (sc_perf_op_ctx == NULL) {
395
SCLogDebug("Counter module has been disabled");
342
399
SCPerfClubTMInst *pctmi = NULL;
343
400
SCPerfClubTMInst *temp = NULL;
344
401
pctmi = sc_perf_op_ctx->pctmi;
346
if (sc_perf_op_ctx != NULL) {
347
if (sc_perf_op_ctx->fp != NULL)
348
fclose(sc_perf_op_ctx->fp);
350
if (sc_perf_op_ctx->file != NULL)
351
SCFree(sc_perf_op_ctx->file);
353
while (pctmi != NULL) {
354
if (pctmi->tm_name != NULL)
355
SCFree(pctmi->tm_name);
357
if (pctmi->head != NULL)
365
SCFree(sc_perf_op_ctx);
403
if (sc_perf_op_ctx->fp != NULL)
404
fclose(sc_perf_op_ctx->fp);
406
if (sc_perf_op_ctx->file != NULL)
407
SCFree(sc_perf_op_ctx->file);
409
while (pctmi != NULL) {
410
if (pctmi->tm_name != NULL)
411
SCFree(pctmi->tm_name);
413
if (pctmi->head != NULL)
421
SCFree(sc_perf_op_ctx);
410
465
SCPerfOutputCounters();
412
467
if (TmThreadsCheckFlag(tv_local, THV_KILL)) {
413
TmThreadsSetFlag(tv_local, THV_CLOSED);
472
TmThreadWaitForFlag(tv_local, THV_DEINIT);
474
TmThreadsSetFlag(tv_local, THV_CLOSED);
462
519
tv = tv_root[TVT_PPT];
463
520
while (tv != NULL) {
464
if (tv->inq == NULL || tv->sc_perf_pctx.head == NULL) {
469
q = &trans_q[tv->inq->id];
471
/* assuming the assignment of an int to be atomic, and even if it's
472
* not, it should be okay */
473
tv->sc_perf_pctx.perf_flag = 1;
475
SCCondSignal(&q->cond_q);
521
if (tv->sc_perf_pctx.head == NULL) {
526
/* assuming the assignment of an int to be atomic, and even if it's
527
* not, it should be okay */
528
tv->sc_perf_pctx.perf_flag = 1;
530
if (tv->inq != NULL) {
531
q = &trans_q[tv->inq->id];
532
SCCondSignal(&q->cond_q);
538
/* mgt threads for flow manager */
539
tv = tv_root[TVT_MGMT];
541
if (tv->sc_perf_pctx.head == NULL) {
546
/* assuming the assignment of an int to be atomic, and even if it's
547
* not, it should be okay */
548
tv->sc_perf_pctx.perf_flag = 1;
480
553
if (TmThreadsCheckFlag(tv_local, THV_KILL)) {
481
TmThreadsSetFlag(tv_local, THV_CLOSED);
558
TmThreadWaitForFlag(tv_local, THV_DEINIT);
560
TmThreadsSetFlag(tv_local, THV_CLOSED);
719
794
exit(EXIT_FAILURE);
722
if ( (pc->type_q = SCMalloc(sizeof(SCPerfCounterTypeQ))) == NULL) {
723
SCPerfReleaseCounter(pc);
797
if ( (pc->type_q = SCMalloc(sizeof(SCPerfCounterTypeQ))) == NULL)
726
799
memset(pc->type_q, 0, sizeof(SCPerfCounterTypeQ));
728
801
pc->type_q->type = type_q;
753
if ( (pc->value->cvalue = SCMalloc(pc->value->size)) == NULL) {
754
SCPerfReleaseCounter(pc);
826
if ( (pc->value->cvalue = SCMalloc(pc->value->size)) == NULL)
757
828
memset(pc->value->cvalue, 0, pc->value->size);
759
830
/* display flag which specifies if the counter should be displayed or not */
949
1020
struct tm local_tm;
950
1021
tms = (struct tm *)localtime_r(&tval.tv_sec, &local_tm);
1023
/* Calculate the Engine uptime */
1024
int up_time = (int)difftime(tval.tv_sec, sc_start_time);
1025
int sec = up_time % 60; // Seconds in a minute
1026
int in_min = up_time / 60;
1027
int min = in_min % 60; // Minutes in a hour
1028
int in_hours = in_min / 60;
1029
int hours = in_hours % 24; // Hours in a day
1030
int days = in_hours / 24;
952
1032
fprintf(sc_perf_op_ctx->fp, "----------------------------------------------"
953
1033
"---------------------\n");
954
fprintf(sc_perf_op_ctx->fp, "%" PRId32 "/%" PRId32 "/%04d -- %02d:%02d:%02d\n",
955
tms->tm_mday, tms->tm_mon + 1, tms->tm_year + 1900, tms->tm_hour,
956
tms->tm_min, tms->tm_sec);
1034
fprintf(sc_perf_op_ctx->fp, "Date: %" PRId32 "/%" PRId32 "/%04d -- "
1035
"%02d:%02d:%02d (uptime: %"PRId32"d, %02dh %02dm %02ds)\n",
1036
tms->tm_mon + 1, tms->tm_mday, tms->tm_year + 1900, tms->tm_hour,
1037
tms->tm_min, tms->tm_sec, days, hours, min, sec);
957
1038
fprintf(sc_perf_op_ctx->fp, "----------------------------------------------"
958
1039
"---------------------\n");
959
1040
fprintf(sc_perf_op_ctx->fp, "%-25s | %-25s | %-s\n", "Counter", "TM Name",
1050
1131
if (pc_heads[u] == NULL ||
1051
1132
(pc_heads[0] != NULL &&
1052
strcmp(pctmi->tm_name, pc_heads[0]->name->tm_name)))
1133
strcmp(pctmi->tm_name, pc_heads[0]->name->tm_name))) {
1056
1138
if (pc->disp == 0 || pc->value == NULL)
1358
1446
int SCPerfAddToClubbedTMTable(char *tm_name, SCPerfContext *pctx)
1448
if (sc_perf_op_ctx == NULL) {
1449
SCLogDebug("Counter module has been disabled");
1360
1453
SCPerfClubTMInst *pctmi = NULL;
1361
1454
SCPerfClubTMInst *prev = NULL;
1362
1455
SCPerfClubTMInst *temp = NULL;
1386
1479
/* get me the bugger who wrote this junk of a code :P */
1387
1480
if (pctmi == NULL) {
1388
if ( (temp = SCMalloc(sizeof(SCPerfClubTMInst))) == NULL) {
1389
SCMutexUnlock(&sc_perf_op_ctx->pctmi_lock);
1481
if ( (temp = SCMalloc(sizeof(SCPerfClubTMInst))) == NULL)
1392
1483
memset(temp, 0, sizeof(SCPerfClubTMInst));
1394
1485
temp->size = 1;
1395
1486
temp->head = SCMalloc(sizeof(SCPerfContext **));
1396
if (temp->head == NULL) {
1398
SCMutexUnlock(&sc_perf_op_ctx->pctmi_lock);
1487
if (temp->head == NULL)
1401
1489
temp->head[0] = pctx;
1402
1490
temp->tm_name = SCStrdup(tm_name);
1423
1511
pctmi->head = SCRealloc(pctmi->head,
1424
(pctmi->size + 1) * sizeof(SCPerfContext *));
1425
if (pctmi->head == NULL) {
1426
SCMutexUnlock(&sc_perf_op_ctx->pctmi_lock);
1512
(pctmi->size + 1) * sizeof(SCPerfContext **));
1513
if (pctmi->head == NULL)
1429
1515
hpctx = pctmi->head;
1431
1517
hpctx[pctmi->size] = pctx;
1480
1566
memset(pca, 0, sizeof(SCPerfCounterArray));
1482
if ( (pca->head = SCMalloc(sizeof(SCPCAElem) * (e_id - s_id + 2))) == NULL) {
1568
if ( (pca->head = SCMalloc(sizeof(SCPCAElem) * (e_id - s_id + 2))) == NULL)
1486
1570
memset(pca->head, 0, sizeof(SCPCAElem) * (e_id - s_id + 2));
1488
1572
pc = pctx->head;
1812
1900
memset(&tv, 0, sizeof(ThreadVars));
1814
pca = (SCPerfCounterArray *)&tv.sc_perf_pca;
1902
//pca = (SCPerfCounterArray *)&tv.sc_perf_pca;
1816
1904
SCPerfRegisterCounter("t1", "c1", SC_PERF_TYPE_UINT64, NULL,
1817
1905
&tv.sc_perf_pctx);
1955
2042
SCPerfUpdateCounterArray(pca, &tv.sc_perf_pctx, 0);
1957
u8p = (uint8_t *)tv.sc_perf_pctx.head->value->cvalue;
1958
result &= (1 == *u8p);
1959
result &= (0 == *(u8p + 1));
1960
result &= (0 == *(u8p + 2));
1961
result &= (0 == *(u8p + 3));
1963
u8p = (uint8_t *)tv.sc_perf_pctx.head->next->value->cvalue;
1964
result &= (0 == *u8p);
1965
result &= (1 == *(u8p + 1));
1966
result &= (0 == *(u8p + 2));
1967
result &= (0 == *(u8p + 3));
1969
u8p = (uint8_t *)tv.sc_perf_pctx.head->next->next->value->cvalue;
1970
result &= (1 == *u8p);
1971
result &= (1 == *(u8p + 1));
1972
result &= (0 == *(u8p + 2));
1973
result &= (0 == *(u8p + 3));
1975
u8p = (uint8_t *)tv.sc_perf_pctx.head->next->next->next->value->cvalue;
1976
result &= (16 == *u8p);
1977
result &= (1 == *(u8p + 1));
1978
result &= (1 == *(u8p + 2));
1979
result &= (1 == *(u8p + 3));
2044
uint64_t *u64p = (uint64_t *)tv.sc_perf_pctx.head->value->cvalue;
2045
result &= (1 == *u64p);
2047
u64p = (uint64_t *)tv.sc_perf_pctx.head->next->value->cvalue;
2048
result &= (256 == *u64p);
2050
u64p = (uint64_t *)tv.sc_perf_pctx.head->next->next->value->cvalue;
2051
result &= (257 == *u64p);
2053
u64p = (uint64_t *)tv.sc_perf_pctx.head->next->next->next->value->cvalue;
2054
result &= (16843024 == *u64p);
1981
2056
SCPerfReleasePerfCounterS(tv.sc_perf_pctx.head);
1982
2057
SCPerfReleasePCA(pca);
2331
#endif /* UNITTESTS */
2333
2407
void SCPerfRegisterTests()
2336
2409
UtRegisterTest("SCPerfTestCounterReg01", SCPerfTestCounterReg01, 0);
2337
2410
UtRegisterTest("SCPerfTestCounterReg02", SCPerfTestCounterReg02, 0);
2338
2411
UtRegisterTest("SCPerfTestCounterReg03", SCPerfTestCounterReg03, 1);
2352
2425
UtRegisterTest("SCPerfTestIntervalQual16", SCPerfTestIntervalQual16, 1);
2353
2426
UtRegisterTest("SCPerfTestIntervalQual17", SCPerfTestIntervalQual17, 1);
2354
2427
UtRegisterTest("SCPerfTestIntervalQual18", SCPerfTestIntervalQual18, 1);