- new configuration support added to ike_sa and states
[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 */
93 void (*set_logger_level) (private_logger_manager_t *this, logger_context_t context,logger_level_t logger_level,bool enable);
94
95 };
96
97
98 typedef struct logger_levels_entry_t logger_levels_entry_t;
99
100 /**
101 * Entry in the logger_levels linked list.
102 *
103 * This entry specifies the current log level for
104 * logger_t objects in specific context.
105 */
106 struct logger_levels_entry_t {
107 logger_context_t context;
108 logger_level_t level;
109 };
110
111 typedef struct loggers_entry_t loggers_entry_t;
112
113 /**
114 * Entry in the loggers linked list.
115 */
116 struct loggers_entry_t {
117 logger_context_t context;
118 logger_t *logger;
119 };
120
121 /**
122 * Implementation of logger_manager_t.create_logger.
123 */
124 static logger_t *create_logger(private_logger_manager_t *this, logger_context_t context, char * name)
125 {
126
127 char * context_name;
128 bool log_thread_ids = TRUE;
129 FILE * output = NULL;
130 char buffer[MAX_LOGGER_NAME];
131 loggers_entry_t *entry;
132 logger_t *logger;
133 logger_level_t logger_level = 0;
134
135 context_name = mapping_find(logger_context_t_mappings,context);
136
137 /* output to stdout, since we are debugging all days */
138 output = stdout;
139
140 switch(context)
141 {
142 case TESTER:
143 log_thread_ids = FALSE;
144 output = stdout;
145 logger_level |= FULL;
146 break;
147 case IKE_SA:
148 logger_level |= FULL;
149 case IKE_SA_MANAGER:
150 case MESSAGE:
151 case WORKER:
152 logger_level |= ALL;
153 break;
154 case PARSER:
155 case GENERATOR:
156 case THREAD_POOL:
157 case SCHEDULER:
158 case SENDER:
159 case RECEIVER:
160 case SOCKET:
161 case DAEMON:
162 case CONFIGURATION_MANAGER:
163 log_thread_ids = FALSE;
164 logger_level |= ERROR|CONTROL;
165 break;
166 }
167
168
169 /* reduce to global definiton of loglevel */
170 logger_level &= this->public.get_logger_level(&(this->public),context);
171
172 /* logger manager is thread save */
173 pthread_mutex_lock(&(this->mutex));
174 if (name != NULL)
175 {
176 snprintf(buffer, MAX_LOGGER_NAME, "%s - %s",context_name,name);
177 /* create logger with default log_level */
178 logger = logger_create(buffer,logger_level,log_thread_ids,output);
179 }
180 else
181 {
182 logger = logger_create(context_name,logger_level,log_thread_ids,output);
183 }
184
185
186 entry = allocator_alloc_thing(loggers_entry_t);
187
188 entry->context = context;
189 entry->logger = logger;
190
191 this->loggers->insert_last(this->loggers,entry);
192
193 pthread_mutex_unlock(&(this->mutex));
194 return logger;
195
196 }
197
198 /**
199 * Implementation of logger_manager_t.get_logger_level.
200 */
201 static logger_level_t get_logger_level (private_logger_manager_t *this, logger_context_t context)
202 {
203 iterator_t *iterator;
204 /* set logger_level to default logger_level */
205 logger_level_t logger_level = this->default_log_level;
206
207 pthread_mutex_lock(&(this->mutex));
208
209 iterator = this->logger_levels->create_iterator(this->logger_levels,TRUE);
210 /* check for existing logger_level entry */
211 while (iterator->has_next(iterator))
212 {
213 logger_levels_entry_t * entry;
214 iterator->current(iterator,(void **)&entry);
215 if (entry->context == context)
216 {
217 logger_level = entry->level;
218 break;
219 }
220 }
221 iterator->destroy(iterator);
222
223 pthread_mutex_unlock(&(this->mutex));
224 return logger_level;
225 }
226
227 /**
228 * Implementation of logger_manager_t.destroy_logger.
229 */
230 static void destroy_logger(private_logger_manager_t *this,logger_t *logger)
231 {
232 iterator_t *iterator;
233
234 pthread_mutex_lock(&(this->mutex));
235
236 iterator = this->loggers->create_iterator(this->loggers,TRUE);
237 while (iterator->has_next(iterator))
238 {
239 loggers_entry_t * entry;
240 iterator->current(iterator,(void **)&entry);
241 if (entry->logger == logger)
242 {
243 iterator->remove(iterator);
244 allocator_free(entry);
245 logger->destroy(logger);
246 break;
247 }
248 }
249 iterator->destroy(iterator);
250 pthread_mutex_unlock(&(this->mutex));
251 }
252
253 /**
254 * Implementation of private_logger_manager_t.set_logger_level.
255 */
256 static void set_logger_level(private_logger_manager_t *this, logger_context_t context,logger_level_t logger_level,bool enable)
257 {
258 iterator_t *iterator;
259 bool found = FALSE;
260
261 pthread_mutex_lock(&(this->mutex));
262 iterator = this->logger_levels->create_iterator(this->logger_levels,TRUE);
263
264 /* find existing logger_level entry */
265 while (iterator->has_next(iterator))
266 {
267 logger_levels_entry_t * entry;
268 iterator->current(iterator,(void **)&entry);
269 if (entry->context == context)
270 {
271 if (enable)
272 {
273 entry->level |= logger_level;
274 }
275 else
276 {
277 entry->level &= ~logger_level;
278 }
279 found = TRUE;
280 break;
281 }
282 }
283 iterator->destroy(iterator);
284
285 if (!found)
286 {
287 /* logger_levels entry not existing for current context */
288 logger_levels_entry_t *entry = allocator_alloc_thing(logger_levels_entry_t);
289
290 entry->context = context;
291 entry->level = (enable) ? logger_level : (this->default_log_level & (~logger_level));
292
293 this->logger_levels->insert_last(this->logger_levels,entry);
294 }
295
296 iterator = this->loggers->create_iterator(this->loggers,TRUE);
297 while (iterator->has_next(iterator))
298 {
299 loggers_entry_t * entry;
300 iterator->current(iterator,(void **)&entry);
301
302 if (entry->context == context)
303 {
304 if (enable)
305 {
306 entry->logger->enable_level(entry->logger,logger_level);
307 }
308 else
309 {
310 entry->logger->disable_level(entry->logger,logger_level);
311 }
312
313 }
314 }
315 iterator->destroy(iterator);
316
317 pthread_mutex_unlock(&(this->mutex));
318 }
319
320 /**
321 * Implementation of logger_manager_t.enable_logger_level.
322 */
323 static void enable_logger_level(private_logger_manager_t *this, logger_context_t context,logger_level_t logger_level)
324 {
325 return set_logger_level(this,context,logger_level,TRUE);
326 }
327
328 /**
329 * Implementation of logger_manager_t.disable_logger_level.
330 */
331 static void disable_logger_level(private_logger_manager_t *this, logger_context_t context,logger_level_t logger_level)
332 {
333 return set_logger_level(this,context,logger_level,FALSE);
334 }
335
336 /**
337 * Implementation of logger_manager_t.destroy.
338 */
339 static void destroy(private_logger_manager_t *this)
340 {
341
342 while (this->loggers->get_count(this->loggers) > 0)
343 {
344 loggers_entry_t *current_entry;
345
346 this->loggers->remove_first(this->loggers,(void **)&current_entry);
347
348 /* destroy logger object */
349 current_entry->logger->destroy(current_entry->logger);
350
351 /* entry can be destroyed */
352 allocator_free(current_entry);
353 }
354
355 while (this->logger_levels->get_count(this->logger_levels) > 0)
356 {
357 logger_levels_entry_t *current_entry;
358
359 this->logger_levels->remove_first(this->logger_levels,(void **)&current_entry);
360
361 /* entry can be destroyed */
362 allocator_free(current_entry);
363 }
364
365 this->loggers->destroy(this->loggers);
366 this->logger_levels->destroy(this->logger_levels);
367 pthread_mutex_destroy(&(this->mutex));
368
369 allocator_free(this);
370 }
371
372 /*
373 * Described in header.
374 */
375 logger_manager_t *logger_manager_create(logger_level_t default_log_level)
376 {
377 private_logger_manager_t *this = allocator_alloc_thing(private_logger_manager_t);
378
379 this->public.create_logger = (logger_t *(*)(logger_manager_t*,logger_context_t context, char *))create_logger;
380 this->public.destroy_logger = (void(*)(logger_manager_t*,logger_t *logger))destroy_logger;
381 this->public.destroy = (void(*)(logger_manager_t*))destroy;
382 this->public.get_logger_level = (logger_level_t (*)(logger_manager_t *, logger_context_t)) get_logger_level;
383 this->public.enable_logger_level = (void (*)(logger_manager_t *, logger_context_t,logger_level_t)) enable_logger_level;
384 this->public.disable_logger_level = (void (*)(logger_manager_t *, logger_context_t,logger_level_t)) disable_logger_level;
385 this->set_logger_level = (void (*)(private_logger_manager_t *, logger_context_t,logger_level_t,bool)) set_logger_level;
386
387 /* private variables */
388 this->loggers = linked_list_create();
389 this->logger_levels = linked_list_create();
390 this->default_log_level = default_log_level;
391
392 pthread_mutex_init(&(this->mutex), NULL);
393
394 return (logger_manager_t*)this;
395 }
396