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