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
93 void (*set_logger_level
) (private_logger_manager_t
*this, logger_context_t context
,logger_level_t logger_level
,bool enable
);
98 typedef struct logger_levels_entry_t logger_levels_entry_t
;
101 * Entry in the logger_levels linked list.
103 * This entry specifies the current log level for
104 * logger_t objects in specific context.
106 struct logger_levels_entry_t
{
107 logger_context_t context
;
108 logger_level_t level
;
111 typedef struct loggers_entry_t loggers_entry_t
;
114 * Entry in the loggers linked list.
116 struct loggers_entry_t
{
117 logger_context_t context
;
122 * Implementation of logger_manager_t.create_logger.
124 static logger_t
*create_logger(private_logger_manager_t
*this, logger_context_t context
, char * name
)
128 bool log_thread_ids
= TRUE
;
129 FILE * output
= NULL
;
130 char buffer
[MAX_LOGGER_NAME
];
131 loggers_entry_t
*entry
;
133 logger_level_t logger_level
= 0;
135 context_name
= mapping_find(logger_context_t_mappings
,context
);
137 /* output to stdout, since we are debugging all days */
143 log_thread_ids
= FALSE
;
145 logger_level
|= FULL
;
148 logger_level
|= FULL
;
161 case CONFIGURATION_MANAGER
:
162 log_thread_ids
= FALSE
;
163 logger_level
|= ERROR
|CONTROL
;
168 /* reduce to global definiton of loglevel */
169 logger_level
&= this->public.get_logger_level(&(this->public),context
);
171 /* logger manager is thread save */
172 pthread_mutex_lock(&(this->mutex
));
175 snprintf(buffer
, MAX_LOGGER_NAME
, "%s - %s",context_name
,name
);
176 /* create logger with default log_level */
177 logger
= logger_create(buffer
,logger_level
,log_thread_ids
,output
);
181 logger
= logger_create(context_name
,logger_level
,log_thread_ids
,output
);
185 entry
= allocator_alloc_thing(loggers_entry_t
);
187 entry
->context
= context
;
188 entry
->logger
= logger
;
190 this->loggers
->insert_last(this->loggers
,entry
);
192 pthread_mutex_unlock(&(this->mutex
));
198 * Implementation of logger_manager_t.get_logger_level.
200 static logger_level_t
get_logger_level (private_logger_manager_t
*this, logger_context_t context
)
202 iterator_t
*iterator
;
203 /* set logger_level to default logger_level */
204 logger_level_t logger_level
= this->default_log_level
;
206 pthread_mutex_lock(&(this->mutex
));
208 iterator
= this->logger_levels
->create_iterator(this->logger_levels
,TRUE
);
209 /* check for existing logger_level entry */
210 while (iterator
->has_next(iterator
))
212 logger_levels_entry_t
* entry
;
213 iterator
->current(iterator
,(void **)&entry
);
214 if (entry
->context
== context
)
216 logger_level
= entry
->level
;
220 iterator
->destroy(iterator
);
222 pthread_mutex_unlock(&(this->mutex
));
227 * Implementation of logger_manager_t.destroy_logger.
229 static void destroy_logger(private_logger_manager_t
*this,logger_t
*logger
)
231 iterator_t
*iterator
;
233 pthread_mutex_lock(&(this->mutex
));
235 iterator
= this->loggers
->create_iterator(this->loggers
,TRUE
);
236 while (iterator
->has_next(iterator
))
238 loggers_entry_t
* entry
;
239 iterator
->current(iterator
,(void **)&entry
);
240 if (entry
->logger
== logger
)
242 iterator
->remove(iterator
);
243 allocator_free(entry
);
244 logger
->destroy(logger
);
248 iterator
->destroy(iterator
);
249 pthread_mutex_unlock(&(this->mutex
));
253 * Implementation of private_logger_manager_t.set_logger_level.
255 static void set_logger_level(private_logger_manager_t
*this, logger_context_t context
,logger_level_t logger_level
,bool enable
)
257 iterator_t
*iterator
;
260 pthread_mutex_lock(&(this->mutex
));
261 iterator
= this->logger_levels
->create_iterator(this->logger_levels
,TRUE
);
263 /* find existing logger_level entry */
264 while (iterator
->has_next(iterator
))
266 logger_levels_entry_t
* entry
;
267 iterator
->current(iterator
,(void **)&entry
);
268 if (entry
->context
== context
)
272 entry
->level
|= logger_level
;
276 entry
->level
&= ~logger_level
;
282 iterator
->destroy(iterator
);
286 /* logger_levels entry not existing for current context */
287 logger_levels_entry_t
*entry
= allocator_alloc_thing(logger_levels_entry_t
);
289 entry
->context
= context
;
290 entry
->level
= (enable
) ? logger_level
: (this->default_log_level
& (~logger_level
));
292 this->logger_levels
->insert_last(this->logger_levels
,entry
);
295 iterator
= this->loggers
->create_iterator(this->loggers
,TRUE
);
296 while (iterator
->has_next(iterator
))
298 loggers_entry_t
* entry
;
299 iterator
->current(iterator
,(void **)&entry
);
301 if (entry
->context
== context
)
305 entry
->logger
->enable_level(entry
->logger
,logger_level
);
309 entry
->logger
->disable_level(entry
->logger
,logger_level
);
314 iterator
->destroy(iterator
);
316 pthread_mutex_unlock(&(this->mutex
));
320 * Implementation of logger_manager_t.enable_logger_level.
322 static void enable_logger_level(private_logger_manager_t
*this, logger_context_t context
,logger_level_t logger_level
)
324 return set_logger_level(this,context
,logger_level
,TRUE
);
328 * Implementation of logger_manager_t.disable_logger_level.
330 static void disable_logger_level(private_logger_manager_t
*this, logger_context_t context
,logger_level_t logger_level
)
332 return set_logger_level(this,context
,logger_level
,FALSE
);
336 * Implementation of logger_manager_t.destroy.
338 static void destroy(private_logger_manager_t
*this)
341 while (this->loggers
->get_count(this->loggers
) > 0)
343 loggers_entry_t
*current_entry
;
345 this->loggers
->remove_first(this->loggers
,(void **)¤t_entry
);
347 /* destroy logger object */
348 current_entry
->logger
->destroy(current_entry
->logger
);
350 /* entry can be destroyed */
351 allocator_free(current_entry
);
354 while (this->logger_levels
->get_count(this->logger_levels
) > 0)
356 logger_levels_entry_t
*current_entry
;
358 this->logger_levels
->remove_first(this->logger_levels
,(void **)¤t_entry
);
360 /* entry can be destroyed */
361 allocator_free(current_entry
);
364 this->loggers
->destroy(this->loggers
);
365 this->logger_levels
->destroy(this->logger_levels
);
366 pthread_mutex_destroy(&(this->mutex
));
368 allocator_free(this);
372 * Described in header.
374 logger_manager_t
*logger_manager_create(logger_level_t default_log_level
)
376 private_logger_manager_t
*this = allocator_alloc_thing(private_logger_manager_t
);
378 this->public.create_logger
= (logger_t
*(*)(logger_manager_t
*,logger_context_t context
, char *))create_logger
;
379 this->public.destroy_logger
= (void(*)(logger_manager_t
*,logger_t
*logger
))destroy_logger
;
380 this->public.destroy
= (void(*)(logger_manager_t
*))destroy
;
381 this->public.get_logger_level
= (logger_level_t (*)(logger_manager_t
*, logger_context_t
)) get_logger_level
;
382 this->public.enable_logger_level
= (void (*)(logger_manager_t
*, logger_context_t
,logger_level_t
)) enable_logger_level
;
383 this->public.disable_logger_level
= (void (*)(logger_manager_t
*, logger_context_t
,logger_level_t
)) disable_logger_level
;
384 this->set_logger_level
= (void (*)(private_logger_manager_t
*, logger_context_t
,logger_level_t
,bool)) set_logger_level
;
386 /* private variables */
387 this->loggers
= linked_list_create();
388 this->logger_levels
= linked_list_create();
389 this->default_log_level
= default_log_level
;
391 pthread_mutex_init(&(this->mutex
), NULL
);
393 return (logger_manager_t
*)this;