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