Use a separate interface for loggers.
[strongswan.git] / src / libcharon / bus / listeners / sys_logger.c
1 /*
2 * Copyright (C) 2012 Tobias Brunner
3 * Copyright (C) 2006 Martin Willi
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include <stdio.h>
18 #include <string.h>
19 #include <syslog.h>
20
21 #include "sys_logger.h"
22
23
24 typedef struct private_sys_logger_t private_sys_logger_t;
25
26 /**
27 * Private data of a sys_logger_t object
28 */
29 struct private_sys_logger_t {
30
31 /**
32 * Public data.
33 */
34 sys_logger_t public;
35
36 /**
37 * syslog facility to use
38 */
39 int facility;
40
41 /**
42 * Maximum level to log, for each group
43 */
44 level_t levels[DBG_MAX];
45
46 /**
47 * Print the name/# of the IKE_SA?
48 */
49 bool ike_name;
50 };
51
52 METHOD(logger_t, log_, void,
53 private_sys_logger_t *this, debug_t group, level_t level, int thread,
54 ike_sa_t* ike_sa, char *format, va_list args)
55 {
56 if (level <= this->levels[group])
57 {
58 char buffer[8192], groupstr[4], namestr[128] = "";
59 char *current = buffer, *next;
60
61 /* write in memory buffer first */
62 vsnprintf(buffer, sizeof(buffer), format, args);
63 /* cache group name and optional name string */
64 snprintf(groupstr, sizeof(groupstr), "%N", debug_names, group);
65
66 if (this->ike_name && ike_sa)
67 {
68 if (ike_sa->get_peer_cfg(ike_sa))
69 {
70 snprintf(namestr, sizeof(namestr), " <%s|%d>",
71 ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa));
72 }
73 else
74 {
75 snprintf(namestr, sizeof(namestr), " <%d>",
76 ike_sa->get_unique_id(ike_sa));
77 }
78 }
79
80 /* do a syslog for every line */
81 while (current)
82 {
83 next = strchr(current, '\n');
84 if (next)
85 {
86 *(next++) = '\0';
87 }
88 syslog(this->facility|LOG_INFO, "%.2d[%s]%s %s\n",
89 thread, groupstr, namestr, current);
90 current = next;
91 }
92 }
93 }
94
95 METHOD(sys_logger_t, set_level, void,
96 private_sys_logger_t *this, debug_t group, level_t level)
97 {
98 if (group < DBG_ANY)
99 {
100 this->levels[group] = level;
101 }
102 else
103 {
104 for (group = 0; group < DBG_MAX; group++)
105 {
106 this->levels[group] = level;
107 }
108 }
109 }
110
111 METHOD(sys_logger_t, destroy, void,
112 private_sys_logger_t *this)
113 {
114 closelog();
115 free(this);
116 }
117
118 /*
119 * Described in header.
120 */
121 sys_logger_t *sys_logger_create(int facility, bool ike_name)
122 {
123 private_sys_logger_t *this;
124
125 INIT(this,
126 .public = {
127 .logger = {
128 .log = _log_,
129 },
130 .set_level = _set_level,
131 .destroy = _destroy,
132 },
133 .facility = facility,
134 .ike_name = ike_name,
135 );
136
137 set_level(this, DBG_ANY, LEVEL_SILENT);
138
139 return &this->public;
140 }