- renamed logger_manager method get_logger to create_logger
[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 create_logger.
93 * @see logger_manager_s.create_logger.
94 */
95 static logger_t *create_logger(private_logger_manager_t *this, logger_context_t context, 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_t *logger;
103 logger_level_t logger_level = this->public.get_logger_level(&(this->public),context);
104
105 switch(context)
106 {
107 case PARSER:
108 context_name = "PARSER";
109 break;
110 case GENERATOR:
111 context_name = "GENERATOR";
112 break;
113 case IKE_SA:
114 context_name = "IKE_SA";
115 break;
116 case MESSAGE:
117 context_name = "MESSAGE";
118 break;
119 case WORKER_THREAD:
120 context_name = "WORKER_THREAD";
121 break;
122 case EVENT_THREAD:
123 context_name = "EVENT_THREAD";
124 break;
125 case SENDER_THREAD:
126 context_name = "SENDER_THREAD";
127 break;
128 case RECEIVER_THREAD:
129 context_name = "RECEIVER_THREAD";
130 break;
131 case THREAD_POOL:
132 context_name = "THREAD_POOL";
133 break;
134 case TESTER:
135 context_name = "TESTER";
136 output = stdout;
137 break;
138 default:
139 context_name = "NO CONTEXT";
140 break;
141 }
142
143 pthread_mutex_lock(&(this->mutex));
144 if (name != NULL)
145 {
146 snprintf(buffer, MAX_LOGGER_NAME, "%s - %s",context_name,name);
147 /* create logger with default log_level */
148 logger = logger_create(buffer,logger_level,output);
149 }
150 else
151 {
152 logger = logger_create(context_name,logger_level,output);
153 }
154
155
156 if (logger == NULL)
157 {
158 pthread_mutex_unlock(&(this->mutex));
159 return NULL;
160 }
161
162 entry = allocator_alloc_thing(loggers_entry_t);
163
164 if (entry == NULL)
165 {
166 logger->destroy(logger);
167 pthread_mutex_unlock(&(this->mutex));
168 return NULL;
169 }
170
171 entry->context = context;
172 entry->logger = logger;
173
174 if (this->loggers->insert_last(this->loggers,entry) != SUCCESS)
175 {
176 allocator_free(entry);
177 logger->destroy(logger);
178 pthread_mutex_unlock(&(this->mutex));
179 return NULL;
180 }
181
182 pthread_mutex_unlock(&(this->mutex));
183 return logger;
184
185 }
186
187 static logger_level_t get_logger_level (private_logger_manager_t *this, logger_context_t context)
188 {
189 linked_list_iterator_t *iterator;
190 logger_level_t logger_level = this->default_log_level;
191
192 pthread_mutex_lock(&(this->mutex));
193
194 if (this->logger_levels->create_iterator(this->logger_levels,&iterator,TRUE) != SUCCESS)
195 {
196 pthread_mutex_unlock(&(this->mutex));
197 return logger_level;
198 }
199 while (iterator->has_next(iterator))
200 {
201
202 logger_levels_entry_t * entry;
203 if (iterator->current(iterator,(void **)&entry) != SUCCESS)
204 {
205 break;
206 }
207 if (entry->context == context)
208 {
209 logger_level = entry->level;
210 break;
211 }
212 }
213
214 iterator->destroy(iterator);
215
216 pthread_mutex_unlock(&(this->mutex));
217 return logger_level;
218 }
219
220 /**
221 * Implements logger_manager_t-function destroy_logger.
222 * @see logger_manager_s.destroy_logger.
223 */
224 static status_t destroy_logger (private_logger_manager_t *this,logger_t *logger)
225 {
226
227 linked_list_iterator_t *iterator;
228 status_t status;
229
230 pthread_mutex_lock(&(this->mutex));
231 if (this->loggers->create_iterator(this->loggers,&iterator,TRUE) != SUCCESS)
232 {
233 pthread_mutex_unlock(&(this->mutex));
234 return OUT_OF_RES;
235 }
236
237 while (iterator->has_next(iterator))
238 {
239
240 loggers_entry_t * entry;
241 status = iterator->current(iterator,(void **)&entry);
242 if (status != SUCCESS)
243 {
244 break;
245 }
246 status = NOT_FOUND;
247 if (entry->logger == logger)
248 {
249 this->loggers->remove(this->loggers,iterator);
250 allocator_free(entry);
251 logger->destroy(logger);
252 status = SUCCESS;
253 break;
254 }
255 }
256 iterator->destroy(iterator);
257 pthread_mutex_unlock(&(this->mutex));
258 return status;
259 }
260
261 /**
262 * Implements private_logger_manager_t-function set_logger_level.
263 * @see private_logger_manager_s.set_logger_level.
264 */
265 static status_t set_logger_level (private_logger_manager_t *this, logger_context_t context,logger_level_t logger_level,bool enable)
266 {
267
268 linked_list_iterator_t *iterator;
269 status_t status;
270
271 pthread_mutex_lock(&(this->mutex));
272 if (this->logger_levels->create_iterator(this->logger_levels,&iterator,TRUE) != SUCCESS)
273 {
274 pthread_mutex_unlock(&(this->mutex));
275 return OUT_OF_RES;
276 }
277
278 status = NOT_FOUND;
279 while (iterator->has_next(iterator))
280 {
281 logger_levels_entry_t * entry;
282 status = iterator->current(iterator,(void **)&entry);
283 if (status != SUCCESS)
284 {
285 iterator->destroy(iterator);
286 pthread_mutex_unlock(&(this->mutex));
287 return status;
288 }
289 status = NOT_FOUND;
290 if (entry->context == context)
291 {
292 if (enable)
293 {
294 entry->level |= logger_level;
295 }
296 else
297 {
298 entry->level &= ~logger_level;
299 }
300
301 status = SUCCESS;
302 break;
303 }
304 }
305 iterator->destroy(iterator);
306
307 if (status == NOT_FOUND)
308 {
309
310 logger_levels_entry_t *entry = allocator_alloc_thing(logger_levels_entry_t);
311 if (entry == NULL)
312 {
313 pthread_mutex_unlock(&(this->mutex));
314 return OUT_OF_RES;
315 }
316 entry->context = context;
317 entry->level = (enable) ? logger_level : this->default_log_level;
318
319 status = this->logger_levels->insert_last(this->logger_levels,entry);
320 if (status != SUCCESS)
321 {
322 pthread_mutex_unlock(&(this->mutex));
323 return status;
324 }
325 }
326
327 if (this->loggers->create_iterator(this->loggers,&iterator,TRUE) != SUCCESS)
328 {
329 pthread_mutex_unlock(&(this->mutex));
330 return OUT_OF_RES;
331 }
332
333 while (iterator->has_next(iterator))
334 {
335
336 loggers_entry_t * entry;
337 status = iterator->current(iterator,(void **)&entry);
338 if (status != SUCCESS)
339 {
340 iterator->destroy(iterator);
341 pthread_mutex_unlock(&(this->mutex));
342 return status;
343 }
344 if (entry->context == context)
345 {
346 if (enable)
347 {
348 status = entry->logger->enable_level(entry->logger,logger_level);
349 }
350 else
351 {
352 status = entry->logger->disable_level(entry->logger,logger_level);
353 }
354
355 }
356 }
357
358 iterator->destroy(iterator);
359 pthread_mutex_unlock(&(this->mutex));
360 return SUCCESS;
361 }
362
363 /**
364 * Implements logger_manager_t-function enable_logger_level.
365 * @see logger_manager_s.enable_logger_level.
366 */
367 static status_t enable_logger_level (private_logger_manager_t *this, logger_context_t context,logger_level_t logger_level)
368 {
369 return set_logger_level(this,context,logger_level,TRUE);
370 }
371
372 /**
373 * Implements logger_manager_t-function disable_logger_level.
374 * @see logger_manager_s.disable_logger_level.
375 */
376 static status_t disable_logger_level (private_logger_manager_t *this, logger_context_t context,logger_level_t logger_level)
377 {
378 return set_logger_level(this,context,logger_level,FALSE);
379 }
380
381 /**
382 * Implements logger_manager_t-function destroy.
383 * @see logger_manager_s.destroy.
384 */
385 static status_t destroy(private_logger_manager_t *this)
386 {
387 while (this->loggers->get_count(this->loggers) > 0)
388 {
389 loggers_entry_t *current_entry;
390
391 this->loggers->remove_first(this->loggers,(void **)&current_entry);
392
393 /* destroy logger object */
394 current_entry->logger->destroy(current_entry->logger);
395
396 /* entry can be destroyed */
397 allocator_free(current_entry);
398 }
399
400 while (this->logger_levels->get_count(this->logger_levels) > 0)
401 {
402 logger_levels_entry_t *current_entry;
403
404 this->logger_levels->remove_first(this->logger_levels,(void **)&current_entry);
405
406 /* entry can be destroyed */
407 allocator_free(current_entry);
408 }
409
410 this->loggers->destroy(this->loggers);
411 this->logger_levels->destroy(this->logger_levels);
412 pthread_mutex_destroy(&(this->mutex));
413
414 allocator_free(this);
415 return SUCCESS;
416 }
417
418 /*
419 * Described in header
420 */
421 logger_manager_t *logger_manager_create(logger_level_t default_log_level)
422 {
423 private_logger_manager_t *this = allocator_alloc_thing(private_logger_manager_t);
424
425 if (this == NULL)
426 {
427 return NULL;
428 }
429
430 this->public.create_logger = (logger_t *(*)(logger_manager_t*,logger_context_t context, char *))create_logger;
431 this->public.destroy_logger = (status_t(*)(logger_manager_t*,logger_t *logger))destroy_logger;
432 this->public.destroy = (status_t(*)(logger_manager_t*))destroy;
433 this->public.get_logger_level = (logger_level_t (*)(logger_manager_t *, logger_context_t)) get_logger_level;
434 this->public.enable_logger_level = (status_t (*)(logger_manager_t *, logger_context_t,logger_level_t)) enable_logger_level;
435 this->public.disable_logger_level = (status_t (*)(logger_manager_t *, logger_context_t,logger_level_t)) disable_logger_level;
436 this->set_logger_level = (status_t (*)(private_logger_manager_t *, logger_context_t,logger_level_t,bool)) set_logger_level;
437
438 /* private variables */
439 this->loggers = linked_list_create();
440
441 if (this->loggers == NULL)
442 {
443 allocator_free(this);
444 return NULL;
445 }
446 this->logger_levels = linked_list_create();
447 if (this->logger_levels == NULL)
448 {
449 this->loggers->destroy(this->loggers);
450 allocator_free(this);
451 return NULL;
452 }
453 this->default_log_level = default_log_level;
454
455 pthread_mutex_init(&(this->mutex), NULL);
456
457 return (logger_manager_t*)this;
458 }
459