suricata
output-stats.c
Go to the documentation of this file.
1 /* Copyright (C) 2014 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Victor Julien <victor@inliniac.net>
22  *
23  * Stats Logger Output registration functions
24  */
25 
26 #include "suricata-common.h"
27 #include "tm-modules.h"
28 #include "output-stats.h"
29 #include "util-validate.h"
30 
31 typedef struct OutputLoggerThreadStore_ {
32  void *thread_data;
35 
36 /** per thread data for this module, contains a list of per thread
37  * data for the packet loggers. */
38 typedef struct OutputLoggerThreadData_ {
41 
42 /* logger instance, a module + a output ctx,
43  * it's perfectly valid that have multiple instances of the same
44  * log module (e.g. http.log) with different output ctx'. */
45 typedef struct OutputStatsLogger_ {
49  const char *name;
54 
55 static OutputStatsLogger *list = NULL;
56 
61 {
62  OutputStatsLogger *op = SCMalloc(sizeof(*op));
63  if (op == NULL)
64  return -1;
65  memset(op, 0x00, sizeof(*op));
66 
67  op->LogFunc = LogFunc;
68  op->output_ctx = output_ctx;
69  op->name = name;
70  op->ThreadInit = ThreadInit;
73 
74  if (list == NULL)
75  list = op;
76  else {
77  OutputStatsLogger *t = list;
78  while (t->next)
79  t = t->next;
80  t->next = op;
81  }
82 
83  SCLogDebug("OutputRegisterStatsLogger happy");
84  return 0;
85 }
86 
88 {
89  DEBUG_VALIDATE_BUG_ON(thread_data == NULL);
90  DEBUG_VALIDATE_BUG_ON(list == NULL);
91 
92  OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data;
93  OutputStatsLogger *logger = list;
94  OutputLoggerThreadStore *store = op_thread_data->store;
95 
96  DEBUG_VALIDATE_BUG_ON(logger == NULL && store != NULL);
97  DEBUG_VALIDATE_BUG_ON(logger != NULL && store == NULL);
98  DEBUG_VALIDATE_BUG_ON(logger == NULL && store == NULL);
99 
100  while (logger && store) {
101  DEBUG_VALIDATE_BUG_ON(logger->LogFunc == NULL);
102 
103  logger->LogFunc(tv, store->thread_data, st);
104 
105  logger = logger->next;
106  store = store->next;
107 
108  DEBUG_VALIDATE_BUG_ON(logger == NULL && store != NULL);
109  DEBUG_VALIDATE_BUG_ON(logger != NULL && store == NULL);
110  }
111 
112  return TM_ECODE_OK;
113 }
114 
115 /** \brief thread init for the tx logger
116  * This will run the thread init functions for the individual registered
117  * loggers */
118 static TmEcode OutputStatsLogThreadInit(ThreadVars *tv, const void *initdata, void **data)
119 {
120  OutputLoggerThreadData *td = SCMalloc(sizeof(*td));
121  if (td == NULL)
122  return TM_ECODE_FAILED;
123  memset(td, 0x00, sizeof(*td));
124 
125  *data = (void *)td;
126 
127  SCLogDebug("OutputStatsLogThreadInit happy (*data %p)", *data);
128 
129  OutputStatsLogger *logger = list;
130  while (logger) {
131  if (logger->ThreadInit) {
132  void *retptr = NULL;
133  if (logger->ThreadInit(tv, (void *)logger->output_ctx, &retptr) == TM_ECODE_OK) {
134  OutputLoggerThreadStore *ts = SCMalloc(sizeof(*ts));
135 /* todo */ BUG_ON(ts == NULL);
136  memset(ts, 0x00, sizeof(*ts));
137 
138  /* store thread handle */
139  ts->thread_data = retptr;
140 
141  if (td->store == NULL) {
142  td->store = ts;
143  } else {
144  OutputLoggerThreadStore *tmp = td->store;
145  while (tmp->next != NULL)
146  tmp = tmp->next;
147  tmp->next = ts;
148  }
149 
150  SCLogDebug("%s is now set up", logger->name);
151  }
152  }
153 
154  logger = logger->next;
155  }
156 
157  SCLogDebug("OutputStatsLogThreadInit happy (*data %p)", *data);
158  return TM_ECODE_OK;
159 }
160 
161 static TmEcode OutputStatsLogThreadDeinit(ThreadVars *tv, void *thread_data)
162 {
163  OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data;
164  OutputLoggerThreadStore *store = op_thread_data->store;
165  OutputStatsLogger *logger = list;
166 
167  while (logger && store) {
168  if (logger->ThreadDeinit) {
169  logger->ThreadDeinit(tv, store->thread_data);
170  }
171  OutputLoggerThreadStore *next_store = store->next;
172  SCFree(store);
173  store = next_store;
174  logger = logger->next;
175  }
176 
177  SCFree(op_thread_data);
178  return TM_ECODE_OK;
179 }
180 
181 static void OutputStatsLogExitPrintStats(ThreadVars *tv, void *thread_data)
182 {
183  OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data;
184  OutputLoggerThreadStore *store = op_thread_data->store;
185  OutputStatsLogger *logger = list;
186 
187  while (logger && store) {
188  if (logger->ThreadExitPrintStats) {
189  logger->ThreadExitPrintStats(tv, store->thread_data);
190  }
191 
192  logger = logger->next;
193  store = store->next;
194  }
195 }
196 
198 {
199  tmm_modules[TMM_STATSLOGGER].name = "__stats_logger__";
200  tmm_modules[TMM_STATSLOGGER].ThreadInit = OutputStatsLogThreadInit;
201  tmm_modules[TMM_STATSLOGGER].ThreadExitPrintStats = OutputStatsLogExitPrintStats;
202  tmm_modules[TMM_STATSLOGGER].ThreadDeinit = OutputStatsLogThreadDeinit;
204 }
205 
207 {
208  if (list != NULL)
209  return 1;
210  return 0;
211 }
212 
214 {
215  OutputStatsLogger *logger = list;
216  while (logger) {
217  OutputStatsLogger *next_logger = logger->next;
218  SCFree(logger);
219  logger = next_logger;
220  }
221  list = NULL;
222 }
#define SCLogDebug(...)
Definition: util-debug.h:335
struct OutputStatsLogger_ OutputStatsLogger
uint8_t cap_flags
Definition: tm-modules.h:67
#define BUG_ON(x)
void(* ThreadExitPrintStatsFunc)(ThreadVars *, void *)
Definition: tm-modules.h:41
OutputLoggerThreadStore * store
Definition: output-file.c:44
int(* StatsLogger)(ThreadVars *, void *thread_data, const StatsTable *)
Definition: output-stats.h:47
int OutputStatsLoggersRegistered(void)
Definition: output-stats.c:206
struct OutputLoggerThreadStore_ OutputLoggerThreadStore
TmEcode(* ThreadDeinitFunc)(ThreadVars *, void *)
Definition: tm-modules.h:40
OutputCtx * output_ctx
Definition: output-stats.c:47
struct OutputLoggerThreadStore_ * next
Definition: output-file.c:38
TmEcode(* ThreadDeinit)(ThreadVars *, void *)
Definition: tm-modules.h:49
TmEcode OutputStatsLog(ThreadVars *tv, void *thread_data, StatsTable *st)
Definition: output-stats.c:87
ThreadExitPrintStatsFunc ThreadExitPrintStats
Definition: output-stats.c:52
const char * name
Definition: output-stats.c:49
ThreadInitFunc ThreadInit
Definition: output-stats.c:50
void(* ThreadExitPrintStats)(ThreadVars *, void *)
Definition: tm-modules.h:48
ThreadDeinitFunc ThreadDeinit
Definition: output-stats.c:51
const char * name
Definition: tm-modules.h:44
#define SCMalloc(a)
Definition: util-mem.h:222
void TmModuleStatsLoggerRegister(void)
Definition: output-stats.c:197
StatsLogger LogFunc
Definition: output-stats.c:46
#define SCFree(a)
Definition: util-mem.h:322
int OutputRegisterStatsLogger(const char *name, StatsLogger LogFunc, OutputCtx *output_ctx, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, ThreadExitPrintStatsFunc ThreadExitPrintStats)
Definition: output-stats.c:57
void OutputStatsShutdown(void)
Definition: output-stats.c:213
TmModule tmm_modules[TMM_SIZE]
Definition: tm-modules.h:73
uint64_t ts
struct OutputLoggerThreadData_ OutputLoggerThreadData
TmEcode(* ThreadInit)(ThreadVars *, const void *, void **)
Definition: tm-modules.h:47
Per thread variable structure.
Definition: threadvars.h:57
TmEcode(* ThreadInitFunc)(ThreadVars *, const void *, void **)
Definition: tm-modules.h:39
struct OutputStatsLogger_ * next
Definition: output-stats.c:48
#define DEBUG_VALIDATE_BUG_ON(exp)