- state ike_sa_init_responded implemented (has some memleaks)
[strongswan.git] / Source / charon / utils / logger_manager.c
1 /**
2 * @file logger_manager.c
3 *
4 * @brief Implementation of logger_manager_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 */
22
23
24 #include "logger_manager.h"
25
26 #include <definitions.h>
27 #include <utils/allocator.h>
28 #include <utils/linked_list.h>
29
30 mapping_t logger_context_t_mappings[] = {
31 {PARSER, "PARSER"},
32 {GENERATOR, "GENRAT"},
33 {IKE_SA, "IKE_SA"},
34 {IKE_SA_MANAGER, "ISAMGR"},
35 {MESSAGE, "MESSAG"},
36 {THREAD_POOL, "THPOOL"},
37 {WORKER, "WORKER"},
38 {SCHEDULER, "SCHEDU"},
39 {SENDER, "SENDER"},
40 {RECEIVER, "RECEVR"},
41 {SOCKET, "SOCKET"},
42 {TESTER, "TESTER"},
43 {DAEMON, "DAEMON"},
44 {CONFIGURATION_MANAGER, "CONFIG"},
45 {ENCRYPTION_PAYLOAD, "ENCPLD"},
46 };
47
48 /**
49 * Maximum length of a logger name
50 */
51 #define MAX_LOGGER_NAME 45
52
53
54 typedef struct private_logger_manager_t private_logger_manager_t;
55
56 /**
57 * Private data of logger_manager_t object.
58 */
59 struct private_logger_manager_t {
60 /**
61 * Public data.
62 */
63 logger_manager_t public;
64
65 /**
66 * Managed loggers.
67 */
68 linked_list_t *loggers;
69
70 /**
71 * Log Levels.
72 */
73 linked_list_t *logger_levels;
74
75 /**
76 * Used to manage logger list.
77 */
78 pthread_mutex_t mutex;
79
80 /**
81 * Default logger level for a created logger used
82 * if no specific logger_level is set.
83 */
84 logger_level_t default_log_level;
85
86 /**
87 * Sets set logger_level of a specific context.
88 *
89 * @param this calling object
90 * @param context context to set level
91 * @param logger_level logger_level to set
92 * @param enable enable specific level or disable it
93 */
94 void (*set_logger_level) (private_logger_manager_t *this, logger_context_t context,logger_level_t logger_level,bool enable);
95
96 };
97
98
99 typedef struct logger_levels_entry_t logger_levels_entry_t;
100
101 /**
102 * Entry in the logger_levels linked list.
103 *
104 * This entry specifies the current log level for
105 * logger_t objects in specific context.
106 */
107 struct logger_levels_entry_t {
108 logger_context_t context;
109 logger_level_t level;
110 };
111
112 typedef struct loggers_entry_t loggers_entry_t;
113
114 /**
115 * Entry in the loggers linked list.
116 */
117 struct loggers_entry_t {
118 logger_context_t context;
119 logger_t *logger;
120 };
121
122 /**
123 * Implementation of logger_manager_t.create_logger.
124 */
125 static logger_t *create_logger(private_logger_manager_t *this, logger_context_t context, char * name)
126 {
127
128 char * context_name;
129 bool log_thread_ids = TRUE;
130 FILE * output = NULL;
131 char buffer[MAX_LOGGER_NAME];
132 loggers_entry_t *entry;
133 logger_t *logger;
134 logger_level_t logger_level = 0;
135
136 context_name = mapping_find(logger_context_t_mappings,context);
137
138 /* output to stdout, since we are debugging all days */
139 output = stdout;
140
141 switch(context)
142 {
143 case TESTER:
144 log_thread_ids = FALSE;
145 output = stdout;
146 logger_level |= FULL;
147 break;
148 case IKE_SA:
149 logger_level |= FULL;
150 case IKE_SA_MANAGER:
151 case MESSAGE:
152 case ENCRYPTION_PAYLOAD:
153 case WORKER:
154 logger_level |= ALL;
155 case PARSER:
156 case GENERATOR:
157 case THREAD_POOL:
158 case SCHEDULER:
159 case SENDER:
160 case RECEIVER:
161 case SOCKET:
162 case DAEMON:
163 case CONFIGURATION_MANAGER:
164 log_thread_ids = FALSE;
165 logger_level |= ERROR|CONTROL;
166 break;
167 }
168
169
170 /* reduce to global definiton of loglevel */
171 logger_level &= this->public.get_logger_level(&(this->public),context);
172
173 /* logger manager is thread save */
174 pthread_mutex_lock(&(this->mutex));
175 if (name != NULL)
176 {
177 snprintf(buffer, MAX_LOGGER_NAME, "%s - %s",context_name,name);
178 /* create logger with default log_level */
179 logger = logger_create(buffer,logger_level,log_thread_ids,output);
180 }
181 else
182 {
183 logger = logger_create(context_name,logger_level,log_thread_ids,output);
184 }
185
186
187 entry = allocator_alloc_thing(loggers_entry_t);
188
189 entry->context = context;
190 entry->logger = logger;
191
192 this->loggers->insert_last(this->loggers,entry);
193
194 pthread_mutex_unlock(&(this->mutex));
195 return logger;
196
197 }
198
199 /**
200 * Implementation of logger_manager_t.get_logger_level.
201 */
202 static logger_level_t get_logger_level (private_logger_manager_t *this, logger_context_t context)
203 {
204 iterator_t *iterator;
205 /* set logger_level to default logger_level */
206 logger_level_t logger_level = this->default_log_level;
207
208 pthread_mutex_lock(&(this->mutex));
209
210 iterator = this->logger_levels->create_iterator(this->logger_levels,TRUE);
211 /* check for existing logger_level entry */
212 while (iterator->has_next(iterator))
213 {
214 logger_levels_entry_t * entry;
215 iterator->current(iterator,(void **)&entry);
216 if (entry->context == context)
217 {
218 logger_level = entry->level;
219 break;
220 }
221 }
222 iterator->destroy(iterator);
223
224 pthread_mutex_unlock(&(this->mutex));
225 return logger_level;
226 }
227
228 /**
229 * Implementation of logger_manager_t.destroy_logger.
230 */
231 static void destroy_logger(private_logger_manager_t *this,logger_t *logger)
232 {
233 iterator_t *iterator;
234
235 pthread_mutex_lock(&(this->mutex));
236
237 iterator = this->loggers->create_iterator(this->loggers,TRUE);
238 while (iterator->has_next(iterator))
239 {
240 loggers_entry_t * entry;
241 iterator->current(iterator,(void **)&entry);
242 if (entry->logger == logger)
243 {
244 iterator->remove(iterator);
245 allocator_free(entry);
246 logger->destroy(logger);
247 break;
248 }
249 }
250 iterator->destroy(iterator);
251 pthread_mutex_unlock(&(this->mutex));
252 }
253
254 /**
255 * Implementation of private_logger_manager_t.set_logger_level.
256 */
257 static void set_logger_level(private_logger_manager_t *this, logger_context_t context,logger_level_t logger_level,bool enable)
258 {
259 iterator_t *iterator;
260 bool found = FALSE;
261
262 pthread_mutex_lock(&(this->mutex));
263 iterator = this->logger_levels->create_iterator(this->logger_levels,TRUE);
264
265 /* find existing logger_level entry */
266 while (iterator->has_next(iterator))
267 {
268 logger_levels_entry_t * entry;
269 iterator->current(iterator,(void **)&entry);
270 if (entry->context == context)
271 {
272 if (enable)
273 {
274 entry->level |= logger_level;
275 }
276 else
277 {
278 entry->level &= ~logger_level;
279 }
280 found = TRUE;
281 break;
282 }
283 }
284 iterator->destroy(iterator);
285
286 if (!found)
287 {
288 /* logger_levels entry not existing for current context */
289 logger_levels_entry_t *entry = allocator_alloc_thing(logger_levels_entry_t);
290
291 entry->context = context;
292 entry->level = (enable) ? logger_level : (this->default_log_level & (~logger_level));
293
294 this->logger_levels->insert_last(this->logger_levels,entry);
295 }
296
297 iterator = this->loggers->create_iterator(this->loggers,TRUE);
298 while (iterator->has_next(iterator))
299 {
300 loggers_entry_t * entry;
301 iterator->current(iterator,(void **)&entry);
302
303 if (entry->context == context)
304 {
305 if (enable)
306 {
307 entry->logger->enable_level(entry->logger,logger_level);
308 }
309 else
310 {
311 entry->logger->disable_level(entry->logger,logger_level);
312 }
313
314 }
315 }
316 iterator->destroy(iterator);
317
318 pthread_mutex_unlock(&(this->mutex));
319 }
320
321 /**
322 * Implementation of logger_manager_t.enable_logger_level.
323 */
324 static void enable_logger_level(private_logger_manager_t *this, logger_context_t context,logger_level_t logger_level)
325 {
326 return set_logger_level(this,context,logger_level,TRUE);
327 }
328
329 /**
330 * Implementation of logger_manager_t.disable_logger_level.
331 */
332 static void disable_logger_level(private_logger_manager_t *this, logger_context_t context,logger_level_t logger_level)
333 {
334 return set_logger_level(this,context,logger_level,FALSE);
335 }
336
337 /**
338 * Implementation of logger_manager_t.destroy.
339 */
340 static void destroy(private_logger_manager_t *this)
341 {
342
343 while (this->loggers->get_count(this->loggers) > 0)
344 {
345 loggers_entry_t *current_entry;
346
347 this->loggers->remove_first(this->loggers,(void **)&current_entry);
348
349 /* destroy logger object */
350 current_entry->logger->destroy(current_entry->logger);
351
352 /* entry can be destroyed */
353 allocator_free(current_entry);
354 }
355
356 while (this->logger_levels->get_count(this->logger_levels) > 0)
357 {
358 logger_levels_entry_t *current_entry;
359
360 this->logger_levels->remove_first(this->logger_levels,(void **)&current_entry);
361
362 /* entry can be destroyed */
363 allocator_free(current_entry);
364 }
365
366 this->loggers->destroy(this->loggers);
367 this->logger_levels->destroy(this->logger_levels);
368 pthread_mutex_destroy(&(this->mutex));
369
370 allocator_free(this);
371 }
372
373 /*
374 * Described in header.
375 */
376 logger_manager_t *logger_manager_create(logger_level_t default_log_level)
377 {
378 private_logger_manager_t *this = allocator_alloc_thing(private_logger_manager_t);
379
380 this->public.create_logger = (logger_t *(*)(logger_manager_t*,logger_context_t context, char *))create_logger;
381 this->public.destroy_logger = (void(*)(logger_manager_t*,logger_t *logger))destroy_logger;
382 this->public.destroy = (void(*)(logger_manager_t*))destroy;
383 this->public.get_logger_level = (logger_level_t (*)(logger_manager_t *, logger_context_t)) get_logger_level;
384 this->public.enable_logger_level = (void (*)(logger_manager_t *, logger_context_t,logger_level_t)) enable_logger_level;
385 this->public.disable_logger_level = (void (*)(logger_manager_t *, logger_context_t,logger_level_t)) disable_logger_level;
386 this->set_logger_level = (void (*)(private_logger_manager_t *, logger_context_t,logger_level_t,bool)) set_logger_level;
387
388 /* private variables */
389 this->loggers = linked_list_create();
390 this->logger_levels = linked_list_create();
391 this->default_log_level = default_log_level;
392
393 pthread_mutex_init(&(this->mutex), NULL);
394
395 return (logger_manager_t*)this;
396 }
397