]>
Commit | Line | Data |
---|---|---|
ffd555f5 JH |
1 | /** |
2 | * @file logger_manager.c | |
3 | * | |
4 | * @brief Logger manager. Manages globaly all logger objects | |
5 | * | |
6 | */ | |
7 | ||
8 | /* | |
9 | * Copyright (C) 2005 Jan Hutter, Martin Willi | |
10 | * Hochschule fuer Technik Rapperswil | |
11 | * | |
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>. | |
16 | * | |
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 | |
20 | * for more details. | |
21 | */ | |
22 | ||
b85d20d1 | 23 | |
ffd555f5 | 24 | #include "logger_manager.h" |
b85d20d1 MW |
25 | |
26 | #include "allocator.h" | |
88878242 | 27 | #include "linked_list.h" |
9c6340cd JH |
28 | #include "../definitions.h" |
29 | ||
30 | mapping_t logger_context_t_mappings[] = { | |
31 | {PARSER, "PARSER"}, | |
41fc4f74 | 32 | {GENERATOR, "GENRAT"}, |
9c6340cd | 33 | {IKE_SA, "IKE_SA"}, |
41fc4f74 MW |
34 | {IKE_SA_MANAGER, "ISAMGR"}, |
35 | {MESSAGE, "MESSAG"}, | |
36 | {THREAD_POOL, "THPOOL"}, | |
37 | {WORKER, "WORKER"}, | |
38 | {SCHEDULER, "SCHEDU"}, | |
39 | {SENDER, "SENDER"}, | |
40 | {RECEIVER, "RECEVR"}, | |
41 | {SOCKET, "SOCKET"}, | |
9c6340cd | 42 | {TESTER, "TESTER"}, |
f4358cb2 | 43 | {DAEMON, "DAEMON"}, |
06d2a398 | 44 | {CONFIGURATION_MANAGER, "CONFIG"}, |
9c6340cd | 45 | }; |
ffd555f5 JH |
46 | |
47 | /** | |
48 | * Maximum length of a logger name | |
49 | */ | |
8166bcec | 50 | #define MAX_LOGGER_NAME 45 |
ffd555f5 JH |
51 | |
52 | typedef struct private_logger_manager_s private_logger_manager_t; | |
53 | struct private_logger_manager_s { | |
54 | /** | |
55 | * Public data. | |
56 | */ | |
57 | logger_manager_t public; | |
58 | ||
59 | /** | |
60 | * Managed loggers. | |
61 | */ | |
62 | linked_list_t *loggers; | |
63 | ||
64 | /** | |
65 | * Log Levels. | |
66 | */ | |
67 | linked_list_t *logger_levels; | |
68 | ||
69 | /** | |
70 | * Used to manage logger list. | |
71 | */ | |
72 | pthread_mutex_t mutex; | |
73 | ||
74 | /** | |
75 | * Default logger level for a created logger used if no specific logger_level is set | |
76 | */ | |
77 | logger_level_t default_log_level; | |
78 | ||
79 | /** | |
80 | * Sets set logger_level of a specific context. | |
81 | * @param this calling object | |
82 | * @param context context to set level | |
83 | * @param logger_level logger_level to set | |
84 | * @param enable enable specific level or disable it | |
85 | * @return SUCCESS | |
86 | */ | |
87 | status_t (*set_logger_level) (private_logger_manager_t *this, logger_context_t context,logger_level_t logger_level,bool enable); | |
88 | ||
89 | }; | |
90 | ||
91 | /** | |
92 | * Entry in the logger_levels linked list | |
93 | */ | |
94 | typedef struct logger_levels_entry_s logger_levels_entry_t; | |
95 | ||
96 | struct logger_levels_entry_s{ | |
97 | logger_context_t context; | |
98 | logger_level_t level; | |
99 | }; | |
100 | ||
101 | /** | |
102 | * Entry in the loggers linked list | |
103 | */ | |
104 | typedef struct loggers_entry_s loggers_entry_t; | |
105 | ||
106 | struct loggers_entry_s{ | |
107 | logger_context_t context; | |
108 | logger_t *logger; | |
109 | }; | |
110 | ||
111 | /** | |
566bbcd1 MW |
112 | * Implements logger_manager_t-function create_logger. |
113 | * @see logger_manager_s.create_logger. | |
ffd555f5 | 114 | */ |
566bbcd1 | 115 | static logger_t *create_logger(private_logger_manager_t *this, logger_context_t context, char * name) |
ffd555f5 JH |
116 | { |
117 | ||
118 | char * context_name; | |
41fc4f74 | 119 | bool log_thread_ids = TRUE; |
ffd555f5 JH |
120 | FILE * output = NULL; |
121 | char buffer[MAX_LOGGER_NAME]; | |
122 | loggers_entry_t *entry; | |
566bbcd1 | 123 | logger_t *logger; |
ffd555f5 | 124 | logger_level_t logger_level = this->public.get_logger_level(&(this->public),context); |
41fc4f74 MW |
125 | |
126 | context_name = mapping_find(logger_context_t_mappings,context); | |
ffd555f5 JH |
127 | |
128 | switch(context) | |
129 | { | |
ffd555f5 | 130 | case TESTER: |
41fc4f74 | 131 | log_thread_ids = FALSE; |
ffd555f5 JH |
132 | output = stdout; |
133 | break; | |
41fc4f74 MW |
134 | case SCHEDULER: |
135 | case SENDER: | |
136 | case RECEIVER: | |
137 | case THREAD_POOL: | |
138 | case SOCKET: | |
139 | case DAEMON: | |
140 | log_thread_ids = FALSE; | |
141 | break; | |
ffd555f5 | 142 | default: |
41fc4f74 | 143 | break; |
ffd555f5 | 144 | } |
083254bb | 145 | /* logger manager is thread save */ |
ffd555f5 | 146 | pthread_mutex_lock(&(this->mutex)); |
96d72d32 JH |
147 | if (name != NULL) |
148 | { | |
149 | snprintf(buffer, MAX_LOGGER_NAME, "%s - %s",context_name,name); | |
150 | /* create logger with default log_level */ | |
41fc4f74 | 151 | logger = logger_create(buffer,logger_level,log_thread_ids,output); |
96d72d32 JH |
152 | } |
153 | else | |
154 | { | |
41fc4f74 | 155 | logger = logger_create(context_name,logger_level,log_thread_ids,output); |
96d72d32 | 156 | } |
ffd555f5 | 157 | |
ffd555f5 | 158 | |
566bbcd1 | 159 | if (logger == NULL) |
ffd555f5 JH |
160 | { |
161 | pthread_mutex_unlock(&(this->mutex)); | |
566bbcd1 | 162 | return NULL; |
ffd555f5 JH |
163 | } |
164 | ||
165 | entry = allocator_alloc_thing(loggers_entry_t); | |
166 | ||
167 | if (entry == NULL) | |
168 | { | |
566bbcd1 | 169 | logger->destroy(logger); |
ffd555f5 | 170 | pthread_mutex_unlock(&(this->mutex)); |
566bbcd1 | 171 | return NULL; |
ffd555f5 JH |
172 | } |
173 | ||
174 | entry->context = context; | |
566bbcd1 | 175 | entry->logger = logger; |
ffd555f5 JH |
176 | |
177 | if (this->loggers->insert_last(this->loggers,entry) != SUCCESS) | |
178 | { | |
179 | allocator_free(entry); | |
566bbcd1 | 180 | logger->destroy(logger); |
ffd555f5 | 181 | pthread_mutex_unlock(&(this->mutex)); |
566bbcd1 | 182 | return NULL; |
ffd555f5 JH |
183 | } |
184 | ||
185 | pthread_mutex_unlock(&(this->mutex)); | |
566bbcd1 | 186 | return logger; |
ffd555f5 JH |
187 | |
188 | } | |
189 | ||
083254bb JH |
190 | /** |
191 | * Implements logger_manager_t-function get_logger_level. | |
192 | * @see logger_manager_s.get_logger_level. | |
193 | */ | |
ffd555f5 JH |
194 | static logger_level_t get_logger_level (private_logger_manager_t *this, logger_context_t context) |
195 | { | |
196 | linked_list_iterator_t *iterator; | |
083254bb | 197 | /* set logger_level to default logger_level */ |
ffd555f5 JH |
198 | logger_level_t logger_level = this->default_log_level; |
199 | ||
200 | pthread_mutex_lock(&(this->mutex)); | |
201 | ||
202 | if (this->logger_levels->create_iterator(this->logger_levels,&iterator,TRUE) != SUCCESS) | |
203 | { | |
204 | pthread_mutex_unlock(&(this->mutex)); | |
205 | return logger_level; | |
206 | } | |
083254bb JH |
207 | |
208 | /* check for existing logger_level entry */ | |
ffd555f5 JH |
209 | while (iterator->has_next(iterator)) |
210 | { | |
211 | ||
212 | logger_levels_entry_t * entry; | |
213 | if (iterator->current(iterator,(void **)&entry) != SUCCESS) | |
214 | { | |
215 | break; | |
216 | } | |
217 | if (entry->context == context) | |
218 | { | |
219 | logger_level = entry->level; | |
220 | break; | |
221 | } | |
222 | } | |
223 | ||
224 | iterator->destroy(iterator); | |
225 | ||
226 | pthread_mutex_unlock(&(this->mutex)); | |
227 | return logger_level; | |
228 | } | |
229 | ||
230 | /** | |
231 | * Implements logger_manager_t-function destroy_logger. | |
232 | * @see logger_manager_s.destroy_logger. | |
233 | */ | |
234 | static status_t destroy_logger (private_logger_manager_t *this,logger_t *logger) | |
235 | { | |
236 | ||
237 | linked_list_iterator_t *iterator; | |
0666a152 | 238 | status_t status = NOT_FOUND; |
ffd555f5 JH |
239 | |
240 | pthread_mutex_lock(&(this->mutex)); | |
241 | if (this->loggers->create_iterator(this->loggers,&iterator,TRUE) != SUCCESS) | |
242 | { | |
243 | pthread_mutex_unlock(&(this->mutex)); | |
244 | return OUT_OF_RES; | |
245 | } | |
246 | ||
247 | while (iterator->has_next(iterator)) | |
248 | { | |
249 | ||
250 | loggers_entry_t * entry; | |
251 | status = iterator->current(iterator,(void **)&entry); | |
252 | if (status != SUCCESS) | |
253 | { | |
254 | break; | |
255 | } | |
256 | status = NOT_FOUND; | |
257 | if (entry->logger == logger) | |
258 | { | |
259 | this->loggers->remove(this->loggers,iterator); | |
260 | allocator_free(entry); | |
261 | logger->destroy(logger); | |
262 | status = SUCCESS; | |
263 | break; | |
264 | } | |
265 | } | |
266 | iterator->destroy(iterator); | |
267 | pthread_mutex_unlock(&(this->mutex)); | |
268 | return status; | |
269 | } | |
270 | ||
271 | /** | |
272 | * Implements private_logger_manager_t-function set_logger_level. | |
273 | * @see private_logger_manager_s.set_logger_level. | |
274 | */ | |
275 | static status_t set_logger_level (private_logger_manager_t *this, logger_context_t context,logger_level_t logger_level,bool enable) | |
276 | { | |
ffd555f5 JH |
277 | linked_list_iterator_t *iterator; |
278 | status_t status; | |
279 | ||
280 | pthread_mutex_lock(&(this->mutex)); | |
281 | if (this->logger_levels->create_iterator(this->logger_levels,&iterator,TRUE) != SUCCESS) | |
282 | { | |
283 | pthread_mutex_unlock(&(this->mutex)); | |
284 | return OUT_OF_RES; | |
285 | } | |
286 | ||
287 | status = NOT_FOUND; | |
083254bb | 288 | /* find existing logger_level entry */ |
ffd555f5 JH |
289 | while (iterator->has_next(iterator)) |
290 | { | |
291 | logger_levels_entry_t * entry; | |
292 | status = iterator->current(iterator,(void **)&entry); | |
293 | if (status != SUCCESS) | |
294 | { | |
295 | iterator->destroy(iterator); | |
296 | pthread_mutex_unlock(&(this->mutex)); | |
297 | return status; | |
298 | } | |
299 | status = NOT_FOUND; | |
300 | if (entry->context == context) | |
301 | { | |
302 | if (enable) | |
303 | { | |
304 | entry->level |= logger_level; | |
305 | } | |
306 | else | |
307 | { | |
308 | entry->level &= ~logger_level; | |
309 | } | |
310 | ||
311 | status = SUCCESS; | |
312 | break; | |
313 | } | |
314 | } | |
315 | iterator->destroy(iterator); | |
316 | ||
317 | if (status == NOT_FOUND) | |
318 | { | |
083254bb | 319 | /* logger_levels entry not existing for current context */ |
ffd555f5 JH |
320 | logger_levels_entry_t *entry = allocator_alloc_thing(logger_levels_entry_t); |
321 | if (entry == NULL) | |
322 | { | |
323 | pthread_mutex_unlock(&(this->mutex)); | |
324 | return OUT_OF_RES; | |
325 | } | |
326 | entry->context = context; | |
083254bb | 327 | entry->level = (enable) ? logger_level : (this->default_log_level & (~logger_level)); |
ffd555f5 JH |
328 | |
329 | status = this->logger_levels->insert_last(this->logger_levels,entry); | |
330 | if (status != SUCCESS) | |
331 | { | |
083254bb | 332 | allocator_free(entry); |
ffd555f5 JH |
333 | pthread_mutex_unlock(&(this->mutex)); |
334 | return status; | |
335 | } | |
336 | } | |
337 | ||
338 | if (this->loggers->create_iterator(this->loggers,&iterator,TRUE) != SUCCESS) | |
339 | { | |
340 | pthread_mutex_unlock(&(this->mutex)); | |
341 | return OUT_OF_RES; | |
342 | } | |
343 | ||
344 | while (iterator->has_next(iterator)) | |
345 | { | |
346 | ||
347 | loggers_entry_t * entry; | |
348 | status = iterator->current(iterator,(void **)&entry); | |
349 | if (status != SUCCESS) | |
350 | { | |
351 | iterator->destroy(iterator); | |
352 | pthread_mutex_unlock(&(this->mutex)); | |
353 | return status; | |
354 | } | |
355 | if (entry->context == context) | |
356 | { | |
357 | if (enable) | |
358 | { | |
359 | status = entry->logger->enable_level(entry->logger,logger_level); | |
360 | } | |
361 | else | |
362 | { | |
363 | status = entry->logger->disable_level(entry->logger,logger_level); | |
364 | } | |
365 | ||
366 | } | |
367 | } | |
368 | ||
369 | iterator->destroy(iterator); | |
370 | pthread_mutex_unlock(&(this->mutex)); | |
371 | return SUCCESS; | |
372 | } | |
373 | ||
374 | /** | |
375 | * Implements logger_manager_t-function enable_logger_level. | |
376 | * @see logger_manager_s.enable_logger_level. | |
377 | */ | |
378 | static status_t enable_logger_level (private_logger_manager_t *this, logger_context_t context,logger_level_t logger_level) | |
379 | { | |
380 | return set_logger_level(this,context,logger_level,TRUE); | |
381 | } | |
382 | ||
383 | /** | |
384 | * Implements logger_manager_t-function disable_logger_level. | |
385 | * @see logger_manager_s.disable_logger_level. | |
386 | */ | |
387 | static status_t disable_logger_level (private_logger_manager_t *this, logger_context_t context,logger_level_t logger_level) | |
388 | { | |
389 | return set_logger_level(this,context,logger_level,FALSE); | |
390 | } | |
391 | ||
392 | /** | |
393 | * Implements logger_manager_t-function destroy. | |
394 | * @see logger_manager_s.destroy. | |
395 | */ | |
396 | static status_t destroy(private_logger_manager_t *this) | |
397 | { | |
06d2a398 | 398 | |
ffd555f5 JH |
399 | while (this->loggers->get_count(this->loggers) > 0) |
400 | { | |
401 | loggers_entry_t *current_entry; | |
402 | ||
403 | this->loggers->remove_first(this->loggers,(void **)¤t_entry); | |
404 | ||
405 | /* destroy logger object */ | |
406 | current_entry->logger->destroy(current_entry->logger); | |
407 | ||
408 | /* entry can be destroyed */ | |
06d2a398 | 409 | allocator_free(current_entry); |
ffd555f5 JH |
410 | } |
411 | ||
412 | while (this->logger_levels->get_count(this->logger_levels) > 0) | |
413 | { | |
414 | logger_levels_entry_t *current_entry; | |
415 | ||
416 | this->logger_levels->remove_first(this->logger_levels,(void **)¤t_entry); | |
417 | ||
418 | /* entry can be destroyed */ | |
419 | allocator_free(current_entry); | |
420 | } | |
421 | ||
422 | this->loggers->destroy(this->loggers); | |
423 | this->logger_levels->destroy(this->logger_levels); | |
424 | pthread_mutex_destroy(&(this->mutex)); | |
425 | ||
426 | allocator_free(this); | |
427 | return SUCCESS; | |
428 | } | |
429 | ||
430 | /* | |
431 | * Described in header | |
432 | */ | |
433 | logger_manager_t *logger_manager_create(logger_level_t default_log_level) | |
434 | { | |
435 | private_logger_manager_t *this = allocator_alloc_thing(private_logger_manager_t); | |
436 | ||
437 | if (this == NULL) | |
438 | { | |
439 | return NULL; | |
440 | } | |
441 | ||
566bbcd1 | 442 | this->public.create_logger = (logger_t *(*)(logger_manager_t*,logger_context_t context, char *))create_logger; |
ffd555f5 JH |
443 | this->public.destroy_logger = (status_t(*)(logger_manager_t*,logger_t *logger))destroy_logger; |
444 | this->public.destroy = (status_t(*)(logger_manager_t*))destroy; | |
445 | this->public.get_logger_level = (logger_level_t (*)(logger_manager_t *, logger_context_t)) get_logger_level; | |
446 | this->public.enable_logger_level = (status_t (*)(logger_manager_t *, logger_context_t,logger_level_t)) enable_logger_level; | |
447 | this->public.disable_logger_level = (status_t (*)(logger_manager_t *, logger_context_t,logger_level_t)) disable_logger_level; | |
448 | this->set_logger_level = (status_t (*)(private_logger_manager_t *, logger_context_t,logger_level_t,bool)) set_logger_level; | |
449 | ||
450 | /* private variables */ | |
451 | this->loggers = linked_list_create(); | |
452 | ||
453 | if (this->loggers == NULL) | |
454 | { | |
455 | allocator_free(this); | |
456 | return NULL; | |
457 | } | |
458 | this->logger_levels = linked_list_create(); | |
459 | if (this->logger_levels == NULL) | |
460 | { | |
461 | this->loggers->destroy(this->loggers); | |
462 | allocator_free(this); | |
463 | return NULL; | |
464 | } | |
465 | this->default_log_level = default_log_level; | |
466 | ||
467 | pthread_mutex_init(&(this->mutex), NULL); | |
468 | ||
469 | return (logger_manager_t*)this; | |
470 | } | |
471 |