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 
30 typedef struct OutputLoggerThreadStore_ {
31  void *thread_data;
34 
35 /** per thread data for this module, contains a list of per thread
36  * data for the packet loggers. */
37 typedef struct OutputLoggerThreadData_ {
40 
41 /* logger instance, a module + a output ctx,
42  * it's perfectly valid that have multiple instances of the same
43  * log module (e.g. http.log) with different output ctx'. */
44 typedef struct OutputStatsLogger_ {
48  const char *name;
53 
54 static OutputStatsLogger *list = NULL;
55 
60 {
61  OutputStatsLogger *op = SCMalloc(sizeof(*op));
62  if (op == NULL)
63  return -1;
64  memset(op, 0x00, sizeof(*op));
65 
66  op->LogFunc = LogFunc;
67  op->output_ctx = output_ctx;
68  op->name = name;
69  op->ThreadInit = ThreadInit;
72 
73  if (list == NULL)
74  list = op;
75  else {
76  OutputStatsLogger *t = list;
77  while (t->next)
78  t = t->next;
79  t->next = op;
80  }
81 
82  SCLogDebug("OutputRegisterStatsLogger happy");
83  return 0;
84 }
85 
87 {
88  BUG_ON(thread_data == NULL);
89  BUG_ON(list == NULL);
90 
91  OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data;
92  OutputStatsLogger *logger = list;
93  OutputLoggerThreadStore *store = op_thread_data->store;
94 
95  BUG_ON(logger == NULL && store != NULL);
96  BUG_ON(logger != NULL && store == NULL);
97  BUG_ON(logger == NULL && store == NULL);
98 
99  logger = list;
100  store = op_thread_data->store;
101  while (logger && store) {
102  BUG_ON(logger->LogFunc == NULL);
103 
104  logger->LogFunc(tv, store->thread_data, st);
105 
106  logger = logger->next;
107  store = store->next;
108 
109  BUG_ON(logger == NULL && store != NULL);
110  BUG_ON(logger != NULL && store == NULL);
111  }
112 
113  return TM_ECODE_OK;
114 }
115 
116 /** \brief thread init for the tx logger
117  * This will run the thread init functions for the individual registered
118  * loggers */
119 static TmEcode OutputStatsLogThreadInit(ThreadVars *tv, const void *initdata, void **data)
120 {
121  OutputLoggerThreadData *td = SCMalloc(sizeof(*td));
122  if (td == NULL)
123  return TM_ECODE_FAILED;
124  memset(td, 0x00, sizeof(*td));
125 
126  *data = (void *)td;
127 
128  SCLogDebug("OutputStatsLogThreadInit happy (*data %p)", *data);
129 
130  OutputStatsLogger *logger = list;
131  while (logger) {
132  if (logger->ThreadInit) {
133  void *retptr = NULL;
134  if (logger->ThreadInit(tv, (void *)logger->output_ctx, &retptr) == TM_ECODE_OK) {
135  OutputLoggerThreadStore *ts = SCMalloc(sizeof(*ts));
136 /* todo */ BUG_ON(ts == NULL);
137  memset(ts, 0x00, sizeof(*ts));
138 
139  /* store thread handle */
140  ts->thread_data = retptr;
141 
142  if (td->store == NULL) {
143  td->store = ts;
144  } else {
145  OutputLoggerThreadStore *tmp = td->store;
146  while (tmp->next != NULL)
147  tmp = tmp->next;
148  tmp->next = ts;
149  }
150 
151  SCLogDebug("%s is now set up", logger->name);
152  }
153  }
154 
155  logger = logger->next;
156  }
157 
158  SCLogDebug("OutputStatsLogThreadInit happy (*data %p)", *data);
159  return TM_ECODE_OK;
160 }
161 
162 static TmEcode OutputStatsLogThreadDeinit(ThreadVars *tv, void *thread_data)
163 {
164  OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data;
165  OutputLoggerThreadStore *store = op_thread_data->store;
166  OutputStatsLogger *logger = list;
167 
168  while (logger && store) {
169  if (logger->ThreadDeinit) {
170  logger->ThreadDeinit(tv, store->thread_data);
171  }
172  OutputLoggerThreadStore *next_store = store->next;
173  SCFree(store);
174  store = next_store;
175  logger = logger->next;
176  }
177 
178  SCFree(op_thread_data);
179  return TM_ECODE_OK;
180 }
181 
182 static void OutputStatsLogExitPrintStats(ThreadVars *tv, void *thread_data)
183 {
184  OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data;
185  OutputLoggerThreadStore *store = op_thread_data->store;
186  OutputStatsLogger *logger = list;
187 
188  while (logger && store) {
189  if (logger->ThreadExitPrintStats) {
190  logger->ThreadExitPrintStats(tv, store->thread_data);
191  }
192 
193  logger = logger->next;
194  store = store->next;
195  }
196 }
197 
199 {
200  tmm_modules[TMM_STATSLOGGER].name = "__stats_logger__";
201  tmm_modules[TMM_STATSLOGGER].ThreadInit = OutputStatsLogThreadInit;
202  tmm_modules[TMM_STATSLOGGER].ThreadExitPrintStats = OutputStatsLogExitPrintStats;
203  tmm_modules[TMM_STATSLOGGER].ThreadDeinit = OutputStatsLogThreadDeinit;
205 }
206 
208 {
209  if (list != NULL)
210  return 1;
211  return 0;
212 }
213 
215 {
216  OutputStatsLogger *logger = list;
217  while (logger) {
218  OutputStatsLogger *next_logger = logger->next;
219  SCFree(logger);
220  logger = next_logger;
221  }
222  list = NULL;
223 }
#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:207
struct OutputLoggerThreadStore_ OutputLoggerThreadStore
TmEcode(* ThreadDeinitFunc)(ThreadVars *, void *)
Definition: tm-modules.h:40
OutputCtx * output_ctx
Definition: output-stats.c:46
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:86
ThreadExitPrintStatsFunc ThreadExitPrintStats
Definition: output-stats.c:51
const char * name
Definition: output-stats.c:48
ThreadInitFunc ThreadInit
Definition: output-stats.c:49
void(* ThreadExitPrintStats)(ThreadVars *, void *)
Definition: tm-modules.h:48
ThreadDeinitFunc ThreadDeinit
Definition: output-stats.c:50
const char * name
Definition: tm-modules.h:44
#define SCMalloc(a)
Definition: util-mem.h:166
void TmModuleStatsLoggerRegister(void)
Definition: output-stats.c:198
StatsLogger LogFunc
Definition: output-stats.c:45
#define SCFree(a)
Definition: util-mem.h:228
int OutputRegisterStatsLogger(const char *name, StatsLogger LogFunc, OutputCtx *output_ctx, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, ThreadExitPrintStatsFunc ThreadExitPrintStats)
Definition: output-stats.c:56
void OutputStatsShutdown(void)
Definition: output-stats.c:214
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:47