2 * @file logger_manager.c
4 * @brief Logger manager. Manages globaly all logger objects
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
52 typedef struct private_logger_manager_t private_logger_manager_t
;
54 struct private_logger_manager_t
{
58 logger_manager_t
public;
63 linked_list_t
*loggers
;
68 linked_list_t
*logger_levels
;
71 * Used to manage logger list.
73 pthread_mutex_t mutex
;
76 * Default logger level for a created logger used if no specific logger_level is set
78 logger_level_t default_log_level
;
81 * Sets set logger_level of a specific context.
82 * @param this calling object
83 * @param context context to set level
84 * @param logger_level logger_level to set
85 * @param enable enable specific level or disable it
88 status_t (*set_logger_level
) (private_logger_manager_t
*this, logger_context_t context
,logger_level_t logger_level
,bool enable
);
93 * Entry in the logger_levels linked list
95 typedef struct logger_levels_entry_t logger_levels_entry_t
;
97 struct logger_levels_entry_t
{
98 logger_context_t context
;
103 * Entry in the loggers linked list
105 typedef struct loggers_entry_t loggers_entry_t
;
107 struct loggers_entry_t
{
108 logger_context_t context
;
113 * Implements logger_manager_t-function create_logger.
114 * @see logger_manager_s.create_logger.
116 static logger_t
*create_logger(private_logger_manager_t
*this, logger_context_t context
, char * name
)
120 bool log_thread_ids
= TRUE
;
121 FILE * output
= NULL
;
122 char buffer
[MAX_LOGGER_NAME
];
123 loggers_entry_t
*entry
;
125 logger_level_t logger_level
= this->public.get_logger_level(&(this->public),context
);
127 context_name
= mapping_find(logger_context_t_mappings
,context
);
132 log_thread_ids
= FALSE
;
141 log_thread_ids
= FALSE
;
146 /* logger manager is thread save */
147 pthread_mutex_lock(&(this->mutex
));
150 snprintf(buffer
, MAX_LOGGER_NAME
, "%s - %s",context_name
,name
);
151 /* create logger with default log_level */
152 logger
= logger_create(buffer
,logger_level
,log_thread_ids
,output
);
156 logger
= logger_create(context_name
,logger_level
,log_thread_ids
,output
);
162 pthread_mutex_unlock(&(this->mutex
));
166 entry
= allocator_alloc_thing(loggers_entry_t
);
170 logger
->destroy(logger
);
171 pthread_mutex_unlock(&(this->mutex
));
175 entry
->context
= context
;
176 entry
->logger
= logger
;
178 if (this->loggers
->insert_last(this->loggers
,entry
) != SUCCESS
)
180 allocator_free(entry
);
181 logger
->destroy(logger
);
182 pthread_mutex_unlock(&(this->mutex
));
186 pthread_mutex_unlock(&(this->mutex
));
192 * Implements logger_manager_t-function get_logger_level.
193 * @see logger_manager_s.get_logger_level.
195 static logger_level_t
get_logger_level (private_logger_manager_t
*this, logger_context_t context
)
197 iterator_t
*iterator
;
198 /* set logger_level to default logger_level */
199 logger_level_t logger_level
= this->default_log_level
;
201 pthread_mutex_lock(&(this->mutex
));
203 if (this->logger_levels
->create_iterator(this->logger_levels
,&iterator
,TRUE
) != SUCCESS
)
205 pthread_mutex_unlock(&(this->mutex
));
209 /* check for existing logger_level entry */
210 while (iterator
->has_next(iterator
))
213 logger_levels_entry_t
* entry
;
214 if (iterator
->current(iterator
,(void **)&entry
) != SUCCESS
)
218 if (entry
->context
== context
)
220 logger_level
= entry
->level
;
225 iterator
->destroy(iterator
);
227 pthread_mutex_unlock(&(this->mutex
));
232 * Implements logger_manager_t-function destroy_logger.
233 * @see logger_manager_s.destroy_logger.
235 static status_t
destroy_logger (private_logger_manager_t
*this,logger_t
*logger
)
238 iterator_t
*iterator
;
239 status_t status
= NOT_FOUND
;
241 pthread_mutex_lock(&(this->mutex
));
242 if (this->loggers
->create_iterator(this->loggers
,&iterator
,TRUE
) != SUCCESS
)
244 pthread_mutex_unlock(&(this->mutex
));
248 while (iterator
->has_next(iterator
))
251 loggers_entry_t
* entry
;
252 status
= iterator
->current(iterator
,(void **)&entry
);
253 if (status
!= SUCCESS
)
258 if (entry
->logger
== logger
)
260 iterator
->remove(iterator
);
261 allocator_free(entry
);
262 logger
->destroy(logger
);
267 iterator
->destroy(iterator
);
268 pthread_mutex_unlock(&(this->mutex
));
273 * Implements private_logger_manager_t-function set_logger_level.
274 * @see private_logger_manager_s.set_logger_level.
276 static status_t
set_logger_level (private_logger_manager_t
*this, logger_context_t context
,logger_level_t logger_level
,bool enable
)
278 iterator_t
*iterator
;
281 pthread_mutex_lock(&(this->mutex
));
282 if (this->logger_levels
->create_iterator(this->logger_levels
,&iterator
,TRUE
) != SUCCESS
)
284 pthread_mutex_unlock(&(this->mutex
));
289 /* find existing logger_level entry */
290 while (iterator
->has_next(iterator
))
292 logger_levels_entry_t
* entry
;
293 status
= iterator
->current(iterator
,(void **)&entry
);
294 if (status
!= SUCCESS
)
296 iterator
->destroy(iterator
);
297 pthread_mutex_unlock(&(this->mutex
));
301 if (entry
->context
== context
)
305 entry
->level
|= logger_level
;
309 entry
->level
&= ~logger_level
;
316 iterator
->destroy(iterator
);
318 if (status
== NOT_FOUND
)
320 /* logger_levels entry not existing for current context */
321 logger_levels_entry_t
*entry
= allocator_alloc_thing(logger_levels_entry_t
);
324 pthread_mutex_unlock(&(this->mutex
));
327 entry
->context
= context
;
328 entry
->level
= (enable
) ? logger_level
: (this->default_log_level
& (~logger_level
));
330 status
= this->logger_levels
->insert_last(this->logger_levels
,entry
);
331 if (status
!= SUCCESS
)
333 allocator_free(entry
);
334 pthread_mutex_unlock(&(this->mutex
));
339 if (this->loggers
->create_iterator(this->loggers
,&iterator
,TRUE
) != SUCCESS
)
341 pthread_mutex_unlock(&(this->mutex
));
345 while (iterator
->has_next(iterator
))
348 loggers_entry_t
* entry
;
349 status
= iterator
->current(iterator
,(void **)&entry
);
350 if (status
!= SUCCESS
)
352 iterator
->destroy(iterator
);
353 pthread_mutex_unlock(&(this->mutex
));
356 if (entry
->context
== context
)
360 status
= entry
->logger
->enable_level(entry
->logger
,logger_level
);
364 status
= entry
->logger
->disable_level(entry
->logger
,logger_level
);
370 iterator
->destroy(iterator
);
371 pthread_mutex_unlock(&(this->mutex
));
376 * Implements logger_manager_t-function enable_logger_level.
377 * @see logger_manager_s.enable_logger_level.
379 static status_t
enable_logger_level (private_logger_manager_t
*this, logger_context_t context
,logger_level_t logger_level
)
381 return set_logger_level(this,context
,logger_level
,TRUE
);
385 * Implements logger_manager_t-function disable_logger_level.
386 * @see logger_manager_s.disable_logger_level.
388 static status_t
disable_logger_level (private_logger_manager_t
*this, logger_context_t context
,logger_level_t logger_level
)
390 return set_logger_level(this,context
,logger_level
,FALSE
);
394 * Implements logger_manager_t-function destroy.
395 * @see logger_manager_s.destroy.
397 static status_t
destroy(private_logger_manager_t
*this)
400 while (this->loggers
->get_count(this->loggers
) > 0)
402 loggers_entry_t
*current_entry
;
404 this->loggers
->remove_first(this->loggers
,(void **)¤t_entry
);
406 /* destroy logger object */
407 current_entry
->logger
->destroy(current_entry
->logger
);
409 /* entry can be destroyed */
410 allocator_free(current_entry
);
413 while (this->logger_levels
->get_count(this->logger_levels
) > 0)
415 logger_levels_entry_t
*current_entry
;
417 this->logger_levels
->remove_first(this->logger_levels
,(void **)¤t_entry
);
419 /* entry can be destroyed */
420 allocator_free(current_entry
);
423 this->loggers
->destroy(this->loggers
);
424 this->logger_levels
->destroy(this->logger_levels
);
425 pthread_mutex_destroy(&(this->mutex
));
427 allocator_free(this);
432 * Described in header
434 logger_manager_t
*logger_manager_create(logger_level_t default_log_level
)
436 private_logger_manager_t
*this = allocator_alloc_thing(private_logger_manager_t
);
443 this->public.create_logger
= (logger_t
*(*)(logger_manager_t
*,logger_context_t context
, char *))create_logger
;
444 this->public.destroy_logger
= (status_t(*)(logger_manager_t
*,logger_t
*logger
))destroy_logger
;
445 this->public.destroy
= (status_t(*)(logger_manager_t
*))destroy
;
446 this->public.get_logger_level
= (logger_level_t (*)(logger_manager_t
*, logger_context_t
)) get_logger_level
;
447 this->public.enable_logger_level
= (status_t (*)(logger_manager_t
*, logger_context_t
,logger_level_t
)) enable_logger_level
;
448 this->public.disable_logger_level
= (status_t (*)(logger_manager_t
*, logger_context_t
,logger_level_t
)) disable_logger_level
;
449 this->set_logger_level
= (status_t (*)(private_logger_manager_t
*, logger_context_t
,logger_level_t
,bool)) set_logger_level
;
451 /* private variables */
452 this->loggers
= linked_list_create();
454 if (this->loggers
== NULL
)
456 allocator_free(this);
459 this->logger_levels
= linked_list_create();
460 if (this->logger_levels
== NULL
)
462 this->loggers
->destroy(this->loggers
);
463 allocator_free(this);
466 this->default_log_level
= default_log_level
;
468 pthread_mutex_init(&(this->mutex
), NULL
);
470 return (logger_manager_t
*)this;