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
;
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
;
162 case CONFIGURATION_MANAGER
:
163 log_thread_ids
= FALSE
;
164 logger_level
= ERROR
|CONTROL
;
169 /* reduce to global definiton of loglevel */
170 logger_level
&= this->public.get_logger_level(&(this->public),context
);
172 /* logger manager is thread save */
173 pthread_mutex_lock(&(this->mutex
));
176 snprintf(buffer
, MAX_LOGGER_NAME
, "%s - %s",context_name
,name
);
177 /* create logger with default log_level */
178 logger
= logger_create(buffer
,logger_level
,log_thread_ids
,output
);
182 logger
= logger_create(context_name
,logger_level
,log_thread_ids
,output
);
188 pthread_mutex_unlock(&(this->mutex
));
192 entry
= allocator_alloc_thing(loggers_entry_t
);
196 logger
->destroy(logger
);
197 pthread_mutex_unlock(&(this->mutex
));
201 entry
->context
= context
;
202 entry
->logger
= logger
;
204 if (this->loggers
->insert_last(this->loggers
,entry
) != SUCCESS
)
206 allocator_free(entry
);
207 logger
->destroy(logger
);
208 pthread_mutex_unlock(&(this->mutex
));
212 pthread_mutex_unlock(&(this->mutex
));
218 * Implementation of logger_manager_t.get_logger_level.
220 static logger_level_t
get_logger_level (private_logger_manager_t
*this, logger_context_t context
)
222 iterator_t
*iterator
;
223 /* set logger_level to default logger_level */
224 logger_level_t logger_level
= this->default_log_level
;
226 pthread_mutex_lock(&(this->mutex
));
228 if (this->logger_levels
->create_iterator(this->logger_levels
,&iterator
,TRUE
) != SUCCESS
)
230 pthread_mutex_unlock(&(this->mutex
));
234 /* check for existing logger_level entry */
235 while (iterator
->has_next(iterator
))
238 logger_levels_entry_t
* entry
;
239 if (iterator
->current(iterator
,(void **)&entry
) != SUCCESS
)
243 if (entry
->context
== context
)
245 logger_level
= entry
->level
;
250 iterator
->destroy(iterator
);
252 pthread_mutex_unlock(&(this->mutex
));
257 * Implementation of logger_manager_t.destroy_logger.
259 static status_t
destroy_logger (private_logger_manager_t
*this,logger_t
*logger
)
262 iterator_t
*iterator
;
263 status_t status
= NOT_FOUND
;
265 pthread_mutex_lock(&(this->mutex
));
266 if (this->loggers
->create_iterator(this->loggers
,&iterator
,TRUE
) != SUCCESS
)
268 pthread_mutex_unlock(&(this->mutex
));
272 while (iterator
->has_next(iterator
))
275 loggers_entry_t
* entry
;
276 status
= iterator
->current(iterator
,(void **)&entry
);
277 if (status
!= SUCCESS
)
282 if (entry
->logger
== logger
)
284 iterator
->remove(iterator
);
285 allocator_free(entry
);
286 logger
->destroy(logger
);
291 iterator
->destroy(iterator
);
292 pthread_mutex_unlock(&(this->mutex
));
297 * Implementation of private_logger_manager_t.set_logger_level.
299 static status_t
set_logger_level (private_logger_manager_t
*this, logger_context_t context
,logger_level_t logger_level
,bool enable
)
301 iterator_t
*iterator
;
304 pthread_mutex_lock(&(this->mutex
));
305 if (this->logger_levels
->create_iterator(this->logger_levels
,&iterator
,TRUE
) != SUCCESS
)
307 pthread_mutex_unlock(&(this->mutex
));
312 /* find existing logger_level entry */
313 while (iterator
->has_next(iterator
))
315 logger_levels_entry_t
* entry
;
316 status
= iterator
->current(iterator
,(void **)&entry
);
317 if (status
!= SUCCESS
)
319 iterator
->destroy(iterator
);
320 pthread_mutex_unlock(&(this->mutex
));
324 if (entry
->context
== context
)
328 entry
->level
|= logger_level
;
332 entry
->level
&= ~logger_level
;
339 iterator
->destroy(iterator
);
341 if (status
== NOT_FOUND
)
343 /* logger_levels entry not existing for current context */
344 logger_levels_entry_t
*entry
= allocator_alloc_thing(logger_levels_entry_t
);
347 pthread_mutex_unlock(&(this->mutex
));
350 entry
->context
= context
;
351 entry
->level
= (enable
) ? logger_level
: (this->default_log_level
& (~logger_level
));
353 status
= this->logger_levels
->insert_last(this->logger_levels
,entry
);
354 if (status
!= SUCCESS
)
356 allocator_free(entry
);
357 pthread_mutex_unlock(&(this->mutex
));
362 if (this->loggers
->create_iterator(this->loggers
,&iterator
,TRUE
) != SUCCESS
)
364 pthread_mutex_unlock(&(this->mutex
));
368 while (iterator
->has_next(iterator
))
371 loggers_entry_t
* entry
;
372 status
= iterator
->current(iterator
,(void **)&entry
);
373 if (status
!= SUCCESS
)
375 iterator
->destroy(iterator
);
376 pthread_mutex_unlock(&(this->mutex
));
379 if (entry
->context
== context
)
383 status
= entry
->logger
->enable_level(entry
->logger
,logger_level
);
387 status
= entry
->logger
->disable_level(entry
->logger
,logger_level
);
393 iterator
->destroy(iterator
);
394 pthread_mutex_unlock(&(this->mutex
));
399 * Implementation of logger_manager_t.enable_logger_level.
401 static status_t
enable_logger_level (private_logger_manager_t
*this, logger_context_t context
,logger_level_t logger_level
)
403 return set_logger_level(this,context
,logger_level
,TRUE
);
407 * Implementation of logger_manager_t.disable_logger_level.
409 static status_t
disable_logger_level (private_logger_manager_t
*this, logger_context_t context
,logger_level_t logger_level
)
411 return set_logger_level(this,context
,logger_level
,FALSE
);
415 * Implementation of logger_manager_t.destroy.
417 static status_t
destroy(private_logger_manager_t
*this)
420 while (this->loggers
->get_count(this->loggers
) > 0)
422 loggers_entry_t
*current_entry
;
424 this->loggers
->remove_first(this->loggers
,(void **)¤t_entry
);
426 /* destroy logger object */
427 current_entry
->logger
->destroy(current_entry
->logger
);
429 /* entry can be destroyed */
430 allocator_free(current_entry
);
433 while (this->logger_levels
->get_count(this->logger_levels
) > 0)
435 logger_levels_entry_t
*current_entry
;
437 this->logger_levels
->remove_first(this->logger_levels
,(void **)¤t_entry
);
439 /* entry can be destroyed */
440 allocator_free(current_entry
);
443 this->loggers
->destroy(this->loggers
);
444 this->logger_levels
->destroy(this->logger_levels
);
445 pthread_mutex_destroy(&(this->mutex
));
447 allocator_free(this);
452 * Described in header.
454 logger_manager_t
*logger_manager_create(logger_level_t default_log_level
)
456 private_logger_manager_t
*this = allocator_alloc_thing(private_logger_manager_t
);
463 this->public.create_logger
= (logger_t
*(*)(logger_manager_t
*,logger_context_t context
, char *))create_logger
;
464 this->public.destroy_logger
= (status_t(*)(logger_manager_t
*,logger_t
*logger
))destroy_logger
;
465 this->public.destroy
= (status_t(*)(logger_manager_t
*))destroy
;
466 this->public.get_logger_level
= (logger_level_t (*)(logger_manager_t
*, logger_context_t
)) get_logger_level
;
467 this->public.enable_logger_level
= (status_t (*)(logger_manager_t
*, logger_context_t
,logger_level_t
)) enable_logger_level
;
468 this->public.disable_logger_level
= (status_t (*)(logger_manager_t
*, logger_context_t
,logger_level_t
)) disable_logger_level
;
469 this->set_logger_level
= (status_t (*)(private_logger_manager_t
*, logger_context_t
,logger_level_t
,bool)) set_logger_level
;
471 /* private variables */
472 this->loggers
= linked_list_create();
474 if (this->loggers
== NULL
)
476 allocator_free(this);
479 this->logger_levels
= linked_list_create();
480 if (this->logger_levels
== NULL
)
482 this->loggers
->destroy(this->loggers
);
483 allocator_free(this);
486 this->default_log_level
= default_log_level
;
488 pthread_mutex_init(&(this->mutex
), NULL
);
490 return (logger_manager_t
*)this;