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 "allocator.h"
27 #include "linked_list.h"
28 #include "../definitions.h"
30 mapping_t logger_context_t_mappings
[] = {
32 {GENERATOR
, "GENERATOR"},
34 {IKE_SA_MANAGER
, "IKE_SA_MANAGER"},
36 {THREAD_POOL
, "THREAD_POOL"},
37 {WORKER_THREAD
, "WORKER_THREAD"},
38 {SCHEDULER_THREAD
, "SCHEDULER_THREAD"},
39 {SENDER_THREAD
, "SENDER_THREAD"},
40 {RECEIVER_THREAD
, "RECEIVER_THREAD"},
46 * Maximum length of a logger name
48 #define MAX_LOGGER_NAME 45
50 typedef struct private_logger_manager_s private_logger_manager_t
;
51 struct private_logger_manager_s
{
55 logger_manager_t
public;
60 linked_list_t
*loggers
;
65 linked_list_t
*logger_levels
;
68 * Used to manage logger list.
70 pthread_mutex_t mutex
;
73 * Default logger level for a created logger used if no specific logger_level is set
75 logger_level_t default_log_level
;
78 * Sets set logger_level of a specific context.
79 * @param this calling object
80 * @param context context to set level
81 * @param logger_level logger_level to set
82 * @param enable enable specific level or disable it
85 status_t (*set_logger_level
) (private_logger_manager_t
*this, logger_context_t context
,logger_level_t logger_level
,bool enable
);
90 * Entry in the logger_levels linked list
92 typedef struct logger_levels_entry_s logger_levels_entry_t
;
94 struct logger_levels_entry_s
{
95 logger_context_t context
;
100 * Entry in the loggers linked list
102 typedef struct loggers_entry_s loggers_entry_t
;
104 struct loggers_entry_s
{
105 logger_context_t context
;
110 * Implements logger_manager_t-function create_logger.
111 * @see logger_manager_s.create_logger.
113 static logger_t
*create_logger(private_logger_manager_t
*this, logger_context_t context
, char * name
)
117 FILE * output
= NULL
;
118 char buffer
[MAX_LOGGER_NAME
];
119 loggers_entry_t
*entry
;
121 logger_level_t logger_level
= this->public.get_logger_level(&(this->public),context
);
126 context_name
= "TESTER";
130 context_name
= mapping_find(logger_context_t_mappings
,context
);
133 /* logger manager is thread save */
134 pthread_mutex_lock(&(this->mutex
));
137 snprintf(buffer
, MAX_LOGGER_NAME
, "%s - %s",context_name
,name
);
138 /* create logger with default log_level */
139 logger
= logger_create(buffer
,logger_level
,output
);
143 logger
= logger_create(context_name
,logger_level
,output
);
149 pthread_mutex_unlock(&(this->mutex
));
153 entry
= allocator_alloc_thing(loggers_entry_t
);
157 logger
->destroy(logger
);
158 pthread_mutex_unlock(&(this->mutex
));
162 entry
->context
= context
;
163 entry
->logger
= logger
;
165 if (this->loggers
->insert_last(this->loggers
,entry
) != SUCCESS
)
167 allocator_free(entry
);
168 logger
->destroy(logger
);
169 pthread_mutex_unlock(&(this->mutex
));
173 pthread_mutex_unlock(&(this->mutex
));
179 * Implements logger_manager_t-function get_logger_level.
180 * @see logger_manager_s.get_logger_level.
182 static logger_level_t
get_logger_level (private_logger_manager_t
*this, logger_context_t context
)
184 linked_list_iterator_t
*iterator
;
185 /* set logger_level to default logger_level */
186 logger_level_t logger_level
= this->default_log_level
;
188 pthread_mutex_lock(&(this->mutex
));
190 if (this->logger_levels
->create_iterator(this->logger_levels
,&iterator
,TRUE
) != SUCCESS
)
192 pthread_mutex_unlock(&(this->mutex
));
196 /* check for existing logger_level entry */
197 while (iterator
->has_next(iterator
))
200 logger_levels_entry_t
* entry
;
201 if (iterator
->current(iterator
,(void **)&entry
) != SUCCESS
)
205 if (entry
->context
== context
)
207 logger_level
= entry
->level
;
212 iterator
->destroy(iterator
);
214 pthread_mutex_unlock(&(this->mutex
));
219 * Implements logger_manager_t-function destroy_logger.
220 * @see logger_manager_s.destroy_logger.
222 static status_t
destroy_logger (private_logger_manager_t
*this,logger_t
*logger
)
225 linked_list_iterator_t
*iterator
;
228 pthread_mutex_lock(&(this->mutex
));
229 if (this->loggers
->create_iterator(this->loggers
,&iterator
,TRUE
) != SUCCESS
)
231 pthread_mutex_unlock(&(this->mutex
));
235 while (iterator
->has_next(iterator
))
238 loggers_entry_t
* entry
;
239 status
= iterator
->current(iterator
,(void **)&entry
);
240 if (status
!= SUCCESS
)
245 if (entry
->logger
== logger
)
247 this->loggers
->remove(this->loggers
,iterator
);
248 allocator_free(entry
);
249 logger
->destroy(logger
);
254 iterator
->destroy(iterator
);
255 pthread_mutex_unlock(&(this->mutex
));
260 * Implements private_logger_manager_t-function set_logger_level.
261 * @see private_logger_manager_s.set_logger_level.
263 static status_t
set_logger_level (private_logger_manager_t
*this, logger_context_t context
,logger_level_t logger_level
,bool enable
)
265 linked_list_iterator_t
*iterator
;
268 pthread_mutex_lock(&(this->mutex
));
269 if (this->logger_levels
->create_iterator(this->logger_levels
,&iterator
,TRUE
) != SUCCESS
)
271 pthread_mutex_unlock(&(this->mutex
));
276 /* find existing logger_level entry */
277 while (iterator
->has_next(iterator
))
279 logger_levels_entry_t
* entry
;
280 status
= iterator
->current(iterator
,(void **)&entry
);
281 if (status
!= SUCCESS
)
283 iterator
->destroy(iterator
);
284 pthread_mutex_unlock(&(this->mutex
));
288 if (entry
->context
== context
)
292 entry
->level
|= logger_level
;
296 entry
->level
&= ~logger_level
;
303 iterator
->destroy(iterator
);
305 if (status
== NOT_FOUND
)
307 /* logger_levels entry not existing for current context */
308 logger_levels_entry_t
*entry
= allocator_alloc_thing(logger_levels_entry_t
);
311 pthread_mutex_unlock(&(this->mutex
));
314 entry
->context
= context
;
315 entry
->level
= (enable
) ? logger_level
: (this->default_log_level
& (~logger_level
));
317 status
= this->logger_levels
->insert_last(this->logger_levels
,entry
);
318 if (status
!= SUCCESS
)
320 allocator_free(entry
);
321 pthread_mutex_unlock(&(this->mutex
));
326 if (this->loggers
->create_iterator(this->loggers
,&iterator
,TRUE
) != SUCCESS
)
328 pthread_mutex_unlock(&(this->mutex
));
332 while (iterator
->has_next(iterator
))
335 loggers_entry_t
* entry
;
336 status
= iterator
->current(iterator
,(void **)&entry
);
337 if (status
!= SUCCESS
)
339 iterator
->destroy(iterator
);
340 pthread_mutex_unlock(&(this->mutex
));
343 if (entry
->context
== context
)
347 status
= entry
->logger
->enable_level(entry
->logger
,logger_level
);
351 status
= entry
->logger
->disable_level(entry
->logger
,logger_level
);
357 iterator
->destroy(iterator
);
358 pthread_mutex_unlock(&(this->mutex
));
363 * Implements logger_manager_t-function enable_logger_level.
364 * @see logger_manager_s.enable_logger_level.
366 static status_t
enable_logger_level (private_logger_manager_t
*this, logger_context_t context
,logger_level_t logger_level
)
368 return set_logger_level(this,context
,logger_level
,TRUE
);
372 * Implements logger_manager_t-function disable_logger_level.
373 * @see logger_manager_s.disable_logger_level.
375 static status_t
disable_logger_level (private_logger_manager_t
*this, logger_context_t context
,logger_level_t logger_level
)
377 return set_logger_level(this,context
,logger_level
,FALSE
);
381 * Implements logger_manager_t-function destroy.
382 * @see logger_manager_s.destroy.
384 static status_t
destroy(private_logger_manager_t
*this)
386 while (this->loggers
->get_count(this->loggers
) > 0)
388 loggers_entry_t
*current_entry
;
390 this->loggers
->remove_first(this->loggers
,(void **)¤t_entry
);
392 /* destroy logger object */
393 current_entry
->logger
->destroy(current_entry
->logger
);
395 /* entry can be destroyed */
396 allocator_free(current_entry
);
399 while (this->logger_levels
->get_count(this->logger_levels
) > 0)
401 logger_levels_entry_t
*current_entry
;
403 this->logger_levels
->remove_first(this->logger_levels
,(void **)¤t_entry
);
405 /* entry can be destroyed */
406 allocator_free(current_entry
);
409 this->loggers
->destroy(this->loggers
);
410 this->logger_levels
->destroy(this->logger_levels
);
411 pthread_mutex_destroy(&(this->mutex
));
413 allocator_free(this);
418 * Described in header
420 logger_manager_t
*logger_manager_create(logger_level_t default_log_level
)
422 private_logger_manager_t
*this = allocator_alloc_thing(private_logger_manager_t
);
429 this->public.create_logger
= (logger_t
*(*)(logger_manager_t
*,logger_context_t context
, char *))create_logger
;
430 this->public.destroy_logger
= (status_t(*)(logger_manager_t
*,logger_t
*logger
))destroy_logger
;
431 this->public.destroy
= (status_t(*)(logger_manager_t
*))destroy
;
432 this->public.get_logger_level
= (logger_level_t (*)(logger_manager_t
*, logger_context_t
)) get_logger_level
;
433 this->public.enable_logger_level
= (status_t (*)(logger_manager_t
*, logger_context_t
,logger_level_t
)) enable_logger_level
;
434 this->public.disable_logger_level
= (status_t (*)(logger_manager_t
*, logger_context_t
,logger_level_t
)) disable_logger_level
;
435 this->set_logger_level
= (status_t (*)(private_logger_manager_t
*, logger_context_t
,logger_level_t
,bool)) set_logger_level
;
437 /* private variables */
438 this->loggers
= linked_list_create();
440 if (this->loggers
== NULL
)
442 allocator_free(this);
445 this->logger_levels
= linked_list_create();
446 if (this->logger_levels
== NULL
)
448 this->loggers
->destroy(this->loggers
);
449 allocator_free(this);
452 this->default_log_level
= default_log_level
;
454 pthread_mutex_init(&(this->mutex
), NULL
);
456 return (logger_manager_t
*)this;