2 * @file logger_manager.c
4 * @brief Implementation of logger_manager_t.
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
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>.
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
24 #include "logger_manager.h"
26 #include <definitions.h>
27 #include <utils/allocator.h>
28 #include <utils/linked_list.h>
30 mapping_t logger_context_t_mappings
[] = {
32 {GENERATOR
, "GENRAT"},
34 {IKE_SA_MANAGER
, "ISAMGR"},
36 {THREAD_POOL
, "THPOOL"},
38 {SCHEDULER
, "SCHEDU"},
44 {CONFIGURATION_MANAGER
, "CONFIG"},
48 * Maximum length of a logger name
50 #define MAX_LOGGER_NAME 45
53 typedef struct private_logger_manager_t private_logger_manager_t
;
56 * Private data of logger_manager_t object.
58 struct private_logger_manager_t
{
62 logger_manager_t
public;
67 linked_list_t
*loggers
;
72 linked_list_t
*logger_levels
;
75 * Used to manage logger list.
77 pthread_mutex_t mutex
;
80 * Default logger level for a created logger used
81 * if no specific logger_level is set.
83 logger_level_t default_log_level
;
86 * Sets set logger_level of a specific context.
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
96 status_t (*set_logger_level
) (private_logger_manager_t
*this, logger_context_t context
,logger_level_t logger_level
,bool enable
);
101 typedef struct logger_levels_entry_t logger_levels_entry_t
;
104 * Entry in the logger_levels linked list.
106 * This entry specifies the current log level for
107 * logger_t objects in specific context.
109 struct logger_levels_entry_t
{
110 logger_context_t context
;
111 logger_level_t level
;
114 typedef struct loggers_entry_t loggers_entry_t
;
117 * Entry in the loggers linked list.
119 struct loggers_entry_t
{
120 logger_context_t context
;
125 * Implementation of logger_manager_t.create_logger.
127 static logger_t
*create_logger(private_logger_manager_t
*this, logger_context_t context
, char * name
)
131 bool log_thread_ids
= TRUE
;
132 FILE * output
= NULL
;
133 char buffer
[MAX_LOGGER_NAME
];
134 loggers_entry_t
*entry
;
136 logger_level_t logger_level
= this->public.get_logger_level(&(this->public),context
);
138 context_name
= mapping_find(logger_context_t_mappings
,context
);
143 log_thread_ids
= FALSE
;
152 log_thread_ids
= FALSE
;
157 /* logger manager is thread save */
158 pthread_mutex_lock(&(this->mutex
));
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
);
167 logger
= logger_create(context_name
,logger_level
,log_thread_ids
,output
);
173 pthread_mutex_unlock(&(this->mutex
));
177 entry
= allocator_alloc_thing(loggers_entry_t
);
181 logger
->destroy(logger
);
182 pthread_mutex_unlock(&(this->mutex
));
186 entry
->context
= context
;
187 entry
->logger
= logger
;
189 if (this->loggers
->insert_last(this->loggers
,entry
) != SUCCESS
)
191 allocator_free(entry
);
192 logger
->destroy(logger
);
193 pthread_mutex_unlock(&(this->mutex
));
197 pthread_mutex_unlock(&(this->mutex
));
203 * Implementation of logger_manager_t.get_logger_level.
205 static logger_level_t
get_logger_level (private_logger_manager_t
*this, logger_context_t context
)
207 iterator_t
*iterator
;
208 /* set logger_level to default logger_level */
209 logger_level_t logger_level
= this->default_log_level
;
211 pthread_mutex_lock(&(this->mutex
));
213 if (this->logger_levels
->create_iterator(this->logger_levels
,&iterator
,TRUE
) != SUCCESS
)
215 pthread_mutex_unlock(&(this->mutex
));
219 /* check for existing logger_level entry */
220 while (iterator
->has_next(iterator
))
223 logger_levels_entry_t
* entry
;
224 if (iterator
->current(iterator
,(void **)&entry
) != SUCCESS
)
228 if (entry
->context
== context
)
230 logger_level
= entry
->level
;
235 iterator
->destroy(iterator
);
237 pthread_mutex_unlock(&(this->mutex
));
242 * Implementation of logger_manager_t.destroy_logger.
244 static status_t
destroy_logger (private_logger_manager_t
*this,logger_t
*logger
)
247 iterator_t
*iterator
;
248 status_t status
= NOT_FOUND
;
250 pthread_mutex_lock(&(this->mutex
));
251 if (this->loggers
->create_iterator(this->loggers
,&iterator
,TRUE
) != SUCCESS
)
253 pthread_mutex_unlock(&(this->mutex
));
257 while (iterator
->has_next(iterator
))
260 loggers_entry_t
* entry
;
261 status
= iterator
->current(iterator
,(void **)&entry
);
262 if (status
!= SUCCESS
)
267 if (entry
->logger
== logger
)
269 iterator
->remove(iterator
);
270 allocator_free(entry
);
271 logger
->destroy(logger
);
276 iterator
->destroy(iterator
);
277 pthread_mutex_unlock(&(this->mutex
));
282 * Implementation of private_logger_manager_t.set_logger_level.
284 static status_t
set_logger_level (private_logger_manager_t
*this, logger_context_t context
,logger_level_t logger_level
,bool enable
)
286 iterator_t
*iterator
;
289 pthread_mutex_lock(&(this->mutex
));
290 if (this->logger_levels
->create_iterator(this->logger_levels
,&iterator
,TRUE
) != SUCCESS
)
292 pthread_mutex_unlock(&(this->mutex
));
297 /* find existing logger_level entry */
298 while (iterator
->has_next(iterator
))
300 logger_levels_entry_t
* entry
;
301 status
= iterator
->current(iterator
,(void **)&entry
);
302 if (status
!= SUCCESS
)
304 iterator
->destroy(iterator
);
305 pthread_mutex_unlock(&(this->mutex
));
309 if (entry
->context
== context
)
313 entry
->level
|= logger_level
;
317 entry
->level
&= ~logger_level
;
324 iterator
->destroy(iterator
);
326 if (status
== NOT_FOUND
)
328 /* logger_levels entry not existing for current context */
329 logger_levels_entry_t
*entry
= allocator_alloc_thing(logger_levels_entry_t
);
332 pthread_mutex_unlock(&(this->mutex
));
335 entry
->context
= context
;
336 entry
->level
= (enable
) ? logger_level
: (this->default_log_level
& (~logger_level
));
338 status
= this->logger_levels
->insert_last(this->logger_levels
,entry
);
339 if (status
!= SUCCESS
)
341 allocator_free(entry
);
342 pthread_mutex_unlock(&(this->mutex
));
347 if (this->loggers
->create_iterator(this->loggers
,&iterator
,TRUE
) != SUCCESS
)
349 pthread_mutex_unlock(&(this->mutex
));
353 while (iterator
->has_next(iterator
))
356 loggers_entry_t
* entry
;
357 status
= iterator
->current(iterator
,(void **)&entry
);
358 if (status
!= SUCCESS
)
360 iterator
->destroy(iterator
);
361 pthread_mutex_unlock(&(this->mutex
));
364 if (entry
->context
== context
)
368 status
= entry
->logger
->enable_level(entry
->logger
,logger_level
);
372 status
= entry
->logger
->disable_level(entry
->logger
,logger_level
);
378 iterator
->destroy(iterator
);
379 pthread_mutex_unlock(&(this->mutex
));
384 * Implementation of logger_manager_t.enable_logger_level.
386 static status_t
enable_logger_level (private_logger_manager_t
*this, logger_context_t context
,logger_level_t logger_level
)
388 return set_logger_level(this,context
,logger_level
,TRUE
);
392 * Implementation of logger_manager_t.disable_logger_level.
394 static status_t
disable_logger_level (private_logger_manager_t
*this, logger_context_t context
,logger_level_t logger_level
)
396 return set_logger_level(this,context
,logger_level
,FALSE
);
400 * Implementation of logger_manager_t.destroy.
402 static status_t
destroy(private_logger_manager_t
*this)
405 while (this->loggers
->get_count(this->loggers
) > 0)
407 loggers_entry_t
*current_entry
;
409 this->loggers
->remove_first(this->loggers
,(void **)¤t_entry
);
411 /* destroy logger object */
412 current_entry
->logger
->destroy(current_entry
->logger
);
414 /* entry can be destroyed */
415 allocator_free(current_entry
);
418 while (this->logger_levels
->get_count(this->logger_levels
) > 0)
420 logger_levels_entry_t
*current_entry
;
422 this->logger_levels
->remove_first(this->logger_levels
,(void **)¤t_entry
);
424 /* entry can be destroyed */
425 allocator_free(current_entry
);
428 this->loggers
->destroy(this->loggers
);
429 this->logger_levels
->destroy(this->logger_levels
);
430 pthread_mutex_destroy(&(this->mutex
));
432 allocator_free(this);
437 * Described in header.
439 logger_manager_t
*logger_manager_create(logger_level_t default_log_level
)
441 private_logger_manager_t
*this = allocator_alloc_thing(private_logger_manager_t
);
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
;
456 /* private variables */
457 this->loggers
= linked_list_create();
459 if (this->loggers
== NULL
)
461 allocator_free(this);
464 this->logger_levels
= linked_list_create();
465 if (this->logger_levels
== NULL
)
467 this->loggers
->destroy(this->loggers
);
468 allocator_free(this);
471 this->default_log_level
= default_log_level
;
473 pthread_mutex_init(&(this->mutex
), NULL
);
475 return (logger_manager_t
*)this;