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
= 0;
138 context_name
= mapping_find(logger_context_t_mappings
,context
);
140 /* output to stdout, since we are debugging all days */
146 log_thread_ids
= FALSE
;
148 logger_level
|= FULL
;
163 case CONFIGURATION_MANAGER
:
164 log_thread_ids
= FALSE
;
165 logger_level
|= ERROR
|CONTROL
;
170 /* reduce to global definiton of loglevel */
171 logger_level
&= this->public.get_logger_level(&(this->public),context
);
173 /* logger manager is thread save */
174 pthread_mutex_lock(&(this->mutex
));
177 snprintf(buffer
, MAX_LOGGER_NAME
, "%s - %s",context_name
,name
);
178 /* create logger with default log_level */
179 logger
= logger_create(buffer
,logger_level
,log_thread_ids
,output
);
183 logger
= logger_create(context_name
,logger_level
,log_thread_ids
,output
);
189 pthread_mutex_unlock(&(this->mutex
));
193 entry
= allocator_alloc_thing(loggers_entry_t
);
197 logger
->destroy(logger
);
198 pthread_mutex_unlock(&(this->mutex
));
202 entry
->context
= context
;
203 entry
->logger
= logger
;
205 if (this->loggers
->insert_last(this->loggers
,entry
) != SUCCESS
)
207 allocator_free(entry
);
208 logger
->destroy(logger
);
209 pthread_mutex_unlock(&(this->mutex
));
213 pthread_mutex_unlock(&(this->mutex
));
219 * Implementation of logger_manager_t.get_logger_level.
221 static logger_level_t
get_logger_level (private_logger_manager_t
*this, logger_context_t context
)
223 iterator_t
*iterator
;
224 /* set logger_level to default logger_level */
225 logger_level_t logger_level
= this->default_log_level
;
227 pthread_mutex_lock(&(this->mutex
));
229 if (this->logger_levels
->create_iterator(this->logger_levels
,&iterator
,TRUE
) != SUCCESS
)
231 pthread_mutex_unlock(&(this->mutex
));
235 /* check for existing logger_level entry */
236 while (iterator
->has_next(iterator
))
239 logger_levels_entry_t
* entry
;
240 if (iterator
->current(iterator
,(void **)&entry
) != SUCCESS
)
244 if (entry
->context
== context
)
246 logger_level
= entry
->level
;
251 iterator
->destroy(iterator
);
253 pthread_mutex_unlock(&(this->mutex
));
258 * Implementation of logger_manager_t.destroy_logger.
260 static status_t
destroy_logger (private_logger_manager_t
*this,logger_t
*logger
)
263 iterator_t
*iterator
;
264 status_t status
= NOT_FOUND
;
266 pthread_mutex_lock(&(this->mutex
));
267 if (this->loggers
->create_iterator(this->loggers
,&iterator
,TRUE
) != SUCCESS
)
269 pthread_mutex_unlock(&(this->mutex
));
273 while (iterator
->has_next(iterator
))
276 loggers_entry_t
* entry
;
277 status
= iterator
->current(iterator
,(void **)&entry
);
278 if (status
!= SUCCESS
)
283 if (entry
->logger
== logger
)
285 iterator
->remove(iterator
);
286 allocator_free(entry
);
287 logger
->destroy(logger
);
292 iterator
->destroy(iterator
);
293 pthread_mutex_unlock(&(this->mutex
));
298 * Implementation of private_logger_manager_t.set_logger_level.
300 static status_t
set_logger_level (private_logger_manager_t
*this, logger_context_t context
,logger_level_t logger_level
,bool enable
)
302 iterator_t
*iterator
;
305 pthread_mutex_lock(&(this->mutex
));
306 if (this->logger_levels
->create_iterator(this->logger_levels
,&iterator
,TRUE
) != SUCCESS
)
308 pthread_mutex_unlock(&(this->mutex
));
313 /* find existing logger_level entry */
314 while (iterator
->has_next(iterator
))
316 logger_levels_entry_t
* entry
;
317 status
= iterator
->current(iterator
,(void **)&entry
);
318 if (status
!= SUCCESS
)
320 iterator
->destroy(iterator
);
321 pthread_mutex_unlock(&(this->mutex
));
325 if (entry
->context
== context
)
329 entry
->level
|= logger_level
;
333 entry
->level
&= ~logger_level
;
340 iterator
->destroy(iterator
);
342 if (status
== NOT_FOUND
)
344 /* logger_levels entry not existing for current context */
345 logger_levels_entry_t
*entry
= allocator_alloc_thing(logger_levels_entry_t
);
348 pthread_mutex_unlock(&(this->mutex
));
351 entry
->context
= context
;
352 entry
->level
= (enable
) ? logger_level
: (this->default_log_level
& (~logger_level
));
354 status
= this->logger_levels
->insert_last(this->logger_levels
,entry
);
355 if (status
!= SUCCESS
)
357 allocator_free(entry
);
358 pthread_mutex_unlock(&(this->mutex
));
363 if (this->loggers
->create_iterator(this->loggers
,&iterator
,TRUE
) != SUCCESS
)
365 pthread_mutex_unlock(&(this->mutex
));
369 while (iterator
->has_next(iterator
))
372 loggers_entry_t
* entry
;
373 status
= iterator
->current(iterator
,(void **)&entry
);
374 if (status
!= SUCCESS
)
376 iterator
->destroy(iterator
);
377 pthread_mutex_unlock(&(this->mutex
));
380 if (entry
->context
== context
)
384 status
= entry
->logger
->enable_level(entry
->logger
,logger_level
);
388 status
= entry
->logger
->disable_level(entry
->logger
,logger_level
);
394 iterator
->destroy(iterator
);
395 pthread_mutex_unlock(&(this->mutex
));
400 * Implementation of logger_manager_t.enable_logger_level.
402 static status_t
enable_logger_level (private_logger_manager_t
*this, logger_context_t context
,logger_level_t logger_level
)
404 return set_logger_level(this,context
,logger_level
,TRUE
);
408 * Implementation of logger_manager_t.disable_logger_level.
410 static status_t
disable_logger_level (private_logger_manager_t
*this, logger_context_t context
,logger_level_t logger_level
)
412 return set_logger_level(this,context
,logger_level
,FALSE
);
416 * Implementation of logger_manager_t.destroy.
418 static status_t
destroy(private_logger_manager_t
*this)
421 while (this->loggers
->get_count(this->loggers
) > 0)
423 loggers_entry_t
*current_entry
;
425 this->loggers
->remove_first(this->loggers
,(void **)¤t_entry
);
427 /* destroy logger object */
428 current_entry
->logger
->destroy(current_entry
->logger
);
430 /* entry can be destroyed */
431 allocator_free(current_entry
);
434 while (this->logger_levels
->get_count(this->logger_levels
) > 0)
436 logger_levels_entry_t
*current_entry
;
438 this->logger_levels
->remove_first(this->logger_levels
,(void **)¤t_entry
);
440 /* entry can be destroyed */
441 allocator_free(current_entry
);
444 this->loggers
->destroy(this->loggers
);
445 this->logger_levels
->destroy(this->logger_levels
);
446 pthread_mutex_destroy(&(this->mutex
));
448 allocator_free(this);
453 * Described in header.
455 logger_manager_t
*logger_manager_create(logger_level_t default_log_level
)
457 private_logger_manager_t
*this = allocator_alloc_thing(private_logger_manager_t
);
464 this->public.create_logger
= (logger_t
*(*)(logger_manager_t
*,logger_context_t context
, char *))create_logger
;
465 this->public.destroy_logger
= (status_t(*)(logger_manager_t
*,logger_t
*logger
))destroy_logger
;
466 this->public.destroy
= (status_t(*)(logger_manager_t
*))destroy
;
467 this->public.get_logger_level
= (logger_level_t (*)(logger_manager_t
*, logger_context_t
)) get_logger_level
;
468 this->public.enable_logger_level
= (status_t (*)(logger_manager_t
*, logger_context_t
,logger_level_t
)) enable_logger_level
;
469 this->public.disable_logger_level
= (status_t (*)(logger_manager_t
*, logger_context_t
,logger_level_t
)) disable_logger_level
;
470 this->set_logger_level
= (status_t (*)(private_logger_manager_t
*, logger_context_t
,logger_level_t
,bool)) set_logger_level
;
472 /* private variables */
473 this->loggers
= linked_list_create();
475 if (this->loggers
== NULL
)
477 allocator_free(this);
480 this->logger_levels
= linked_list_create();
481 if (this->logger_levels
== NULL
)
483 this->loggers
->destroy(this->loggers
);
484 allocator_free(this);
487 this->default_log_level
= default_log_level
;
489 pthread_mutex_init(&(this->mutex
), NULL
);
491 return (logger_manager_t
*)this;