- first attempt for connection loading and starting via "stroke"
[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 <daemon.h>
27 #include <definitions.h>
28 #include <utils/allocator.h>
29 #include <utils/linked_list.h>
30
31 /**
32 * String mappings for logger_context_t
33 */
34 mapping_t logger_context_t_mappings[] = {
35 {PARSER, "PARSER"},
36 {GENERATOR, "GENRAT"},
37 {IKE_SA, "IKE_SA"},
38 {IKE_SA_MANAGER, "ISAMGR"},
39 {CHILD_SA, "CHLDSA"},
40 {MESSAGE, "MESSAG"},
41 {THREAD_POOL, "THPOOL"},
42 {WORKER, "WORKER"},
43 {SCHEDULER, "SCHEDU"},
44 {SENDER, "SENDER"},
45 {RECEIVER, "RECEVR"},
46 {SOCKET, "SOCKET"},
47 {TESTER, "TESTER"},
48 {DAEMON, "DAEMON"},
49 {CONFIG, "CONFIG"},
50 {ENCRYPTION_PAYLOAD, "ENCPLD"},
51 {MAPPING_END, NULL},
52 };
53
54 /**
55 * Maximum length of a logger name in bytes.
56 */
57 #define MAX_LOGGER_NAME 45
58
59
60 typedef struct private_logger_manager_t private_logger_manager_t;
61
62 /**
63 * Private data of logger_manager_t object.
64 */
65 struct private_logger_manager_t {
66 /**
67 * Public data.
68 */
69 logger_manager_t public;
70
71 /**
72 * List of managed loggers.
73 */
74 linked_list_t *loggers;
75
76 /**
77 * Log Levels.
78 */
79 linked_list_t *logger_levels;
80
81 /**
82 * Used to manage logger list.
83 */
84 pthread_mutex_t mutex;
85
86 /**
87 * Default logger level for a created logger used
88 * if no specific logger_level is set.
89 */
90 logger_level_t default_log_level;
91
92 /**
93 * Sets set logger_level of a specific context.
94 *
95 * @param this calling object
96 * @param context context to set level
97 * @param logger_level logger_level to set
98 * @param enable enable specific level or disable it
99 */
100 void (*set_logger_level) (private_logger_manager_t *this,
101 logger_context_t context,
102 logger_level_t logger_level,
103 bool enable);
104
105 };
106
107
108 typedef struct logger_levels_entry_t logger_levels_entry_t;
109
110 /**
111 * Entry in the logger_levels linked list.
112 *
113 * This entry specifies the current log level for
114 * logger_t objects in specific context.
115 */
116 struct logger_levels_entry_t {
117 /**
118 * Logger context.
119 */
120 logger_context_t context;
121
122 /**
123 * Logger level of logger context.
124 */
125 logger_level_t level;
126 };
127
128
129 typedef struct loggers_entry_t loggers_entry_t;
130
131 /**
132 * Entry in the loggers linked list.
133 *
134 * @todo Replace loggers_entry_t with logger_t and add get_context() function to logger_t class.
135 */
136 struct loggers_entry_t {
137 /**
138 * Logger context.
139 */
140 logger_context_t context;
141 /**
142 * Assigned logger
143 */
144 logger_t *logger;
145 };
146
147 /**
148 * Implementation of logger_manager_t.create_logger.
149 */
150 static logger_t *create_logger(private_logger_manager_t *this, logger_context_t context, char * name)
151 {
152
153 char * context_name;
154 bool log_thread_ids = TRUE;
155 FILE * output = NULL;
156 char buffer[MAX_LOGGER_NAME];
157 loggers_entry_t *entry;
158 logger_t *logger;
159 logger_level_t logger_level = 0;
160
161 context_name = mapping_find(logger_context_t_mappings,context);
162
163 /* output to stdout, since we are debugging all days */
164 output = LOG_OUTPUT;
165
166 /* defaults */
167 log_thread_ids = FALSE;
168 logger_level = this->public.get_logger_level(&(this->public),context);
169
170 switch(context)
171 {
172 case TESTER:
173 output = stdout;
174 break;
175 case IKE_SA_MANAGER:
176 log_thread_ids = TRUE;
177 break;
178 case IKE_SA:
179 logger_level |= LEVEL1;
180 log_thread_ids = TRUE;
181 break;
182 case CHILD_SA:
183 logger_level |= LEVEL1;
184 log_thread_ids = TRUE;
185 break;
186 case CONFIG:
187 logger_level |= FULL;
188 log_thread_ids = TRUE;
189 break;
190 case MESSAGE:
191 log_thread_ids = TRUE;
192 break;
193 case ENCRYPTION_PAYLOAD:
194 log_thread_ids = TRUE;
195 break;
196 case GENERATOR:
197 log_thread_ids = TRUE;
198 break;
199 case PARSER:
200 log_thread_ids = TRUE;
201 break;
202 case WORKER:
203 log_thread_ids = TRUE;
204 break;
205 case THREAD_POOL:
206 break;
207 case SCHEDULER:
208 logger_level = 0;
209 break;
210 case SENDER:
211 break;
212 case RECEIVER:
213 break;
214 case SOCKET:
215 logger_level |= FULL;
216 break;
217 case DAEMON:
218 break;
219 }
220
221 /* logger manager is thread save */
222 pthread_mutex_lock(&(this->mutex));
223 if (name != NULL)
224 {
225 snprintf(buffer, MAX_LOGGER_NAME, "%s - %s",context_name,name);
226 /* create logger with default log_level */
227 logger = logger_create(buffer,logger_level,log_thread_ids,output);
228 }
229 else
230 {
231 logger = logger_create(context_name,logger_level,log_thread_ids,output);
232 }
233
234
235 entry = allocator_alloc_thing(loggers_entry_t);
236
237 entry->context = context;
238 entry->logger = logger;
239
240 this->loggers->insert_last(this->loggers,entry);
241
242 pthread_mutex_unlock(&(this->mutex));
243 return logger;
244
245 }
246
247 /**
248 * Implementation of logger_manager_t.get_logger_level.
249 */
250 static logger_level_t get_logger_level (private_logger_manager_t *this, logger_context_t context)
251 {
252 iterator_t *iterator;
253 /* set logger_level to default logger_level */
254 logger_level_t logger_level = this->default_log_level;
255
256 pthread_mutex_lock(&(this->mutex));
257
258 iterator = this->logger_levels->create_iterator(this->logger_levels,TRUE);
259 /* check for existing logger_level entry */
260 while (iterator->has_next(iterator))
261 {
262 logger_levels_entry_t * entry;
263 iterator->current(iterator,(void **)&entry);
264 if (entry->context == context)
265 {
266 logger_level = entry->level;
267 break;
268 }
269 }
270 iterator->destroy(iterator);
271
272 pthread_mutex_unlock(&(this->mutex));
273 return logger_level;
274 }
275
276 /**
277 * Implementation of logger_manager_t.destroy_logger.
278 */
279 static void destroy_logger(private_logger_manager_t *this,logger_t *logger)
280 {
281 iterator_t *iterator;
282
283 pthread_mutex_lock(&(this->mutex));
284
285 iterator = this->loggers->create_iterator(this->loggers,TRUE);
286 while (iterator->has_next(iterator))
287 {
288 loggers_entry_t * entry;
289 iterator->current(iterator,(void **)&entry);
290 if (entry->logger == logger)
291 {
292 iterator->remove(iterator);
293 allocator_free(entry);
294 logger->destroy(logger);
295 break;
296 }
297 }
298 iterator->destroy(iterator);
299 pthread_mutex_unlock(&(this->mutex));
300 }
301
302 /**
303 * Implementation of private_logger_manager_t.set_logger_level.
304 */
305 static void set_logger_level(private_logger_manager_t *this, logger_context_t context,logger_level_t logger_level,bool enable)
306 {
307 iterator_t *iterator;
308 bool found = FALSE;
309
310 pthread_mutex_lock(&(this->mutex));
311 iterator = this->logger_levels->create_iterator(this->logger_levels,TRUE);
312
313 /* find existing logger_level entry */
314 while (iterator->has_next(iterator))
315 {
316 logger_levels_entry_t * entry;
317 iterator->current(iterator,(void **)&entry);
318 if (entry->context == context)
319 {
320 if (enable)
321 {
322 entry->level |= logger_level;
323 }
324 else
325 {
326 entry->level &= ~logger_level;
327 }
328 found = TRUE;
329 break;
330 }
331 }
332 iterator->destroy(iterator);
333
334 if (!found)
335 {
336 /* logger_levels entry not existing for current context */
337 logger_levels_entry_t *entry = allocator_alloc_thing(logger_levels_entry_t);
338
339 entry->context = context;
340 entry->level = (enable) ? logger_level : (this->default_log_level & (~logger_level));
341
342 this->logger_levels->insert_last(this->logger_levels,entry);
343 }
344
345 iterator = this->loggers->create_iterator(this->loggers,TRUE);
346 while (iterator->has_next(iterator))
347 {
348 loggers_entry_t * entry;
349 iterator->current(iterator,(void **)&entry);
350
351 if (entry->context == context)
352 {
353 if (enable)
354 {
355 entry->logger->enable_level(entry->logger,logger_level);
356 }
357 else
358 {
359 entry->logger->disable_level(entry->logger,logger_level);
360 }
361
362 }
363 }
364 iterator->destroy(iterator);
365
366 pthread_mutex_unlock(&(this->mutex));
367 }
368
369 /**
370 * Implementation of logger_manager_t.enable_logger_level.
371 */
372 static void enable_logger_level(private_logger_manager_t *this, logger_context_t context,logger_level_t logger_level)
373 {
374 return set_logger_level(this,context,logger_level,TRUE);
375 }
376
377 /**
378 * Implementation of logger_manager_t.disable_logger_level.
379 */
380 static void disable_logger_level(private_logger_manager_t *this, logger_context_t context,logger_level_t logger_level)
381 {
382 return set_logger_level(this,context,logger_level,FALSE);
383 }
384
385 /**
386 * Implementation of logger_manager_t.destroy.
387 */
388 static void destroy(private_logger_manager_t *this)
389 {
390
391 while (this->loggers->get_count(this->loggers) > 0)
392 {
393 loggers_entry_t *current_entry;
394
395 this->loggers->remove_first(this->loggers,(void **)&current_entry);
396
397 /* destroy logger object */
398 current_entry->logger->destroy(current_entry->logger);
399
400 /* entry can be destroyed */
401 allocator_free(current_entry);
402 }
403
404 while (this->logger_levels->get_count(this->logger_levels) > 0)
405 {
406 logger_levels_entry_t *current_entry;
407
408 this->logger_levels->remove_first(this->logger_levels,(void **)&current_entry);
409
410 /* entry can be destroyed */
411 allocator_free(current_entry);
412 }
413
414 this->loggers->destroy(this->loggers);
415 this->logger_levels->destroy(this->logger_levels);
416 pthread_mutex_destroy(&(this->mutex));
417
418 allocator_free(this);
419 }
420
421 /*
422 * Described in header.
423 */
424 logger_manager_t *logger_manager_create(logger_level_t default_log_level)
425 {
426 private_logger_manager_t *this = allocator_alloc_thing(private_logger_manager_t);
427
428 this->public.create_logger = (logger_t *(*)(logger_manager_t*,logger_context_t context, char *))create_logger;
429 this->public.destroy_logger = (void(*)(logger_manager_t*,logger_t *logger))destroy_logger;
430 this->public.destroy = (void(*)(logger_manager_t*))destroy;
431 this->public.get_logger_level = (logger_level_t (*)(logger_manager_t *, logger_context_t)) get_logger_level;
432 this->public.enable_logger_level = (void (*)(logger_manager_t *, logger_context_t,logger_level_t)) enable_logger_level;
433 this->public.disable_logger_level = (void (*)(logger_manager_t *, logger_context_t,logger_level_t)) disable_logger_level;
434 this->set_logger_level = (void (*)(private_logger_manager_t *, logger_context_t,logger_level_t,bool)) set_logger_level;
435
436 /* private variables */
437 this->loggers = linked_list_create();
438 this->logger_levels = linked_list_create();
439 this->default_log_level = default_log_level;
440
441 pthread_mutex_init(&(this->mutex), NULL);
442
443 return (logger_manager_t*)this;
444 }
445