da0f85c5f4b816acfde46ac8f40e71a15e49abb4
[strongswan.git] / Source / charon / logger.c
1 /**
2 * @file logger.c
3 *
4 * @brief Logger object, allows fine-controlled logging
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
23
24
25 #include "logger.h"
26 #include "types.h"
27 #include "allocator.h"
28
29 #include <syslog.h>
30 #include <stdarg.h>
31 #include <string.h>
32 #include <stdio.h>
33
34 /**
35 * Maximum length of al log entry (only used for logger_s.log)
36 */
37 #define MAX_LOG 8192
38
39 /**
40 * @brief The logger object
41 */
42 typedef struct private_logger_s private_logger_t;
43 struct private_logger_s {
44 /**
45 * Public data
46 */
47 logger_t public;
48 /**
49 * detail-level of logger
50 */
51 logger_level_t level;
52 /**
53 * name of logger
54 */
55 char *name;
56 };
57
58
59 /**
60 * implements logger_t-function log
61 * @see logger_s.log
62 */
63 static status_t logg(private_logger_t *this, logger_level_t loglevel, char *format, ...)
64 {
65 if ((this->level & loglevel) == loglevel)
66 {
67 char buffer[MAX_LOG];
68 snprintf(buffer, MAX_LOG, "%s: %s", this->name, format);
69 va_list args;
70 va_start(args, format);
71 vsyslog(LOG_INFO, buffer, args);
72 va_end(args);
73 }
74
75 return SUCCESS;
76 }
77
78
79 /**
80 * implements logger_t-function destroy
81 * @see logger_s.log_bytes
82 */
83 static status_t log_bytes(private_logger_t *this, logger_level_t loglevel, char *label, char *bytes, size_t len)
84 {
85 if ((this->level & loglevel) == loglevel)
86 {
87 char buffer[64];
88 char *buffer_pos;
89 char *bytes_pos, *bytes_roof;
90 int i;
91
92 syslog(LOG_INFO, "%s: %s (%d bytes)", this->name, label, len);
93
94 bytes_pos = bytes;
95 bytes_roof = bytes + len;
96 buffer_pos = buffer;
97
98 for (i = 1; bytes_pos < bytes_roof; i++)
99 {
100 static const char hexdig[] = "0123456789ABCDEF";
101 *buffer_pos++ = hexdig[(*bytes_pos >> 4) & 0xF];
102 *buffer_pos++ = hexdig[ *bytes_pos & 0xF];
103 if ((i % 16) == 0)
104 {
105 *buffer_pos++ = '\0';
106 buffer_pos = buffer;
107 syslog(LOG_INFO, "| %s", buffer);
108 }
109 else if ((i % 8) == 0)
110 {
111 *buffer_pos++ = ' ';
112 *buffer_pos++ = ' ';
113 *buffer_pos++ = ' ';
114 }
115 else if ((i % 4) == 0)
116 {
117 *buffer_pos++ = ' ';
118 *buffer_pos++ = ' ';
119 }
120 else
121 {
122 *buffer_pos++ = ' ';
123 }
124
125 bytes_pos++;
126 }
127
128 *buffer_pos++ = '\0';
129 buffer_pos = buffer;
130 syslog(LOG_INFO, "| %s", buffer);
131 }
132
133 return SUCCESS;
134 }
135
136
137 /**
138 * implements logger_t-function log_chunk
139 * @see logger_s.log_chunk
140 */
141 static status_t log_chunk(logger_t *this, logger_level_t loglevel, char *label, chunk_t *chunk)
142 {
143 this->log_bytes(this, loglevel, label, chunk->ptr, chunk->len);
144 return SUCCESS;
145 }
146
147
148 /**
149 * implements logger_t-function enable_level
150 * @see logger_s.enable_level
151 */
152 static status_t enable_level(private_logger_t *this, logger_level_t log_level)
153 {
154 this->level |= log_level;
155 return SUCCESS;
156 }
157
158 /**
159 * implements logger_t-function disable_level
160 * @see logger_s.disable_level
161 */
162 static status_t disable_level(private_logger_t *this, logger_level_t log_level)
163 {
164 this->level &= ~log_level;
165 return SUCCESS;
166 }
167
168 /**
169 * implements logger_t-function destroy
170 * @see logger_s.destroy
171 */
172 static status_t destroy(private_logger_t *this)
173 {
174 allocator_free(this);
175 return SUCCESS;
176 }
177
178 /*
179 * Described in Header
180 */
181 logger_t *logger_create(char *logger_name, logger_level_t log_level)
182 {
183 private_logger_t *this = allocator_alloc_thing(private_logger_t);
184
185 if (this == NULL)
186 {
187 return NULL;
188 }
189
190 this->public.log = (status_t(*)(logger_t*,logger_level_t,char*,...))logg;
191 this->public.log_bytes = (status_t(*)(logger_t*, logger_level_t, char*,char*,size_t))log_bytes;
192 this->public.log_chunk = log_chunk;
193 this->public.enable_level = (status_t(*)(logger_t*,logger_level_t))enable_level;
194 this->public.disable_level = (status_t(*)(logger_t*,logger_level_t))disable_level;
195 this->public.destroy = (status_t(*)(logger_t*))destroy;
196
197 this->level = log_level;
198 this->name = logger_name;
199
200 openlog("charon", 0, LOG_DAEMON);
201
202 return (logger_t*)this;
203 }