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