1 /*
2 * uhub - A tiny ADC p2p connection hub
3 * Copyright (C) 2007-2014, Jan Vidar Krey
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 */
19
20 #include "uhub.h"
21 #include <locale.h>
22
23 #ifndef WIN32
24
25 #ifdef SYSTEMD
26 #define SD_JOURNAL_SUPPRESS_LOCATION
27 #include <systemd/sd-journal.h>
28
29 #else
30 #include <syslog.h>
31 #endif
32
33 static int use_syslog = 0;
34 #endif
35
36 static int verbosity = 4;
37 static FILE* logfile = NULL;
38
39 #ifdef MEMORY_DEBUG
40 static FILE* memfile = NULL;
41 #define MEMORY_DEBUG_FILE "memlog.txt"
42 #endif
43
44 #ifdef NETWORK_DUMP_DEBUG
45 #define NETWORK_DUMP_FILE "netdump.log"
46 static FILE* netdump = NULL;
47 #endif
48
49
50 static const char* prefixes[] =
51 {
52 "FATAL",
53 "ERROR",
54 "WARN",
55 "USER",
56 "INFO",
57 "DEBUG",
58 "TRACE",
59 "DUMP",
60 "MEM",
61 "PROTO",
62 "PLUGIN",
63 0
64 };
65
66
hub_log_initialize(const char * file,int syslog)67 void hub_log_initialize(const char* file, int syslog)
68 {
69
70 setlocale(LC_ALL, "C");
71
72 #ifdef MEMORY_DEBUG
73 memfile = fopen(MEMORY_DEBUG_FILE, "w");
74 if (!memfile)
75 {
76 fprintf(stderr, "Unable to create " MEMORY_DEBUG_FILE " for logging memory allocations\n");
77 return;
78 }
79 #endif
80
81 #ifdef NETWORK_DUMP_DEBUG
82 netdump = fopen(NETWORK_DUMP_FILE, "w");
83 if (!netdump)
84 {
85 fprintf(stderr, "Unable to create " NETWORK_DUMP_FILE " for logging network traffic\n");
86 return;
87 }
88 #endif
89
90 #ifndef WIN32
91 if (syslog)
92 {
93 use_syslog = 1;
94 #ifndef SYSTEMD
95 openlog("uhub", LOG_PID, LOG_USER);
96 #endif
97 }
98 #endif
99
100
101 if (!file)
102 {
103 logfile = stderr;
104 return;
105 }
106
107 logfile = fopen(file, "a");
108 if (!logfile)
109 {
110 logfile = stderr;
111 return;
112 }
113
114 }
115
116
hub_log_shutdown()117 void hub_log_shutdown()
118 {
119 if (logfile && logfile != stderr)
120 {
121 fclose(logfile);
122 logfile = NULL;
123 }
124
125 #ifdef MEMORY_DEBUG
126 if (memfile)
127 {
128 fclose(memfile);
129 memfile = NULL;
130 }
131 #endif
132
133 #ifdef NETWORK_DUMP_DEBUG
134 if (netdump)
135 {
136 fclose(netdump);
137 netdump = NULL;
138 }
139 #endif
140
141 #ifndef WIN32
142 if (use_syslog)
143 {
144 use_syslog = 0;
145 #ifndef SYSTEMD
146 closelog();
147 #endif
148 }
149 #endif
150 }
151
152
hub_set_log_verbosity(int verb)153 void hub_set_log_verbosity(int verb)
154 {
155 verbosity = verb;
156 }
157
hub_log(int log_verbosity,const char * format,...)158 void hub_log(int log_verbosity, const char *format, ...)
159 {
160 static char logmsg[1024];
161 static char timestamp[32];
162 struct tm *tmp;
163 time_t t;
164 va_list args;
165
166 #ifdef MEMORY_DEBUG
167 if (memfile && log_verbosity == log_memory)
168 {
169 va_start(args, format);
170 vsnprintf(logmsg, 1024, format, args);
171 va_end(args);
172 fprintf(memfile, "%s\n", logmsg);
173 fflush(memfile);
174 return;
175 }
176 #endif
177
178 #ifdef NETWORK_DUMP_DEBUG
179 if (netdump && log_verbosity == log_protocol)
180 {
181 va_start(args, format);
182 vsnprintf(logmsg, 1024, format, args);
183 va_end(args);
184 fprintf(netdump, "%s\n", logmsg);
185 fflush(netdump);
186 return;
187 }
188 #endif
189
190 if (log_verbosity < verbosity)
191 {
192 t = time(NULL);
193 tmp = localtime(&t);
194 strftime(timestamp, 32, "%Y-%m-%d %H:%M:%S", tmp);
195 va_start(args, format);
196 vsnprintf(logmsg, 1024, format, args);
197 va_end(args);
198
199 if (logfile)
200 {
201 fprintf(logfile, "%s %6s: %s\n", timestamp, prefixes[log_verbosity], logmsg);
202 fflush(logfile);
203 }
204 else
205 {
206 fprintf(stderr, "%s %6s: %s\n", timestamp, prefixes[log_verbosity], logmsg);
207 }
208 }
209
210 #ifndef WIN32
211 if (use_syslog)
212 {
213 int level = 0;
214
215 if (verbosity < log_info)
216 return;
217
218 va_start(args, format);
219 vsnprintf(logmsg, 1024, format, args);
220 va_end(args);
221
222 switch (log_verbosity)
223 {
224 case log_fatal: level = LOG_CRIT; break;
225 case log_error: level = LOG_ERR; break;
226 case log_warning: level = LOG_WARNING; break;
227 #ifdef SYSTEMD
228 case log_user: level = LOG_INFO; break;
229
230 #else
231 case log_user: level = LOG_INFO | LOG_AUTH; break;
232 #endif
233 case log_info: level = LOG_INFO; break;
234 case log_debug: level = LOG_DEBUG; break;
235
236 default:
237 level = 0;
238 break;
239 }
240
241 if (level == 0)
242 return;
243
244 #ifdef SYSTEMD
245 sd_journal_print(level, "%s", logmsg);
246
247 #else
248 level |= (LOG_USER | LOG_DAEMON);
249 syslog(level, "%s", logmsg);
250 #endif
251 }
252 #endif
253
254 }
255