/
mms_log.h
290 lines (260 loc) · 9.05 KB
/
mms_log.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
/*
* Copyright (C) 2013-2014 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef JOLLA_MMS_LOG_H
#define JOLLA_MMS_LOG_H
#include "mms_lib_types.h"
#include <stdarg.h>
/* Log levels */
#define MMS_LOGLEVEL_GLOBAL (-1)
#define MMS_LOGLEVEL_NONE (0)
#define MMS_LOGLEVEL_ERR (1)
#define MMS_LOGLEVEL_WARN (2)
#define MMS_LOGLEVEL_INFO (3)
#define MMS_LOGLEVEL_DEBUG (4)
#define MMS_LOGLEVEL_VERBOSE (5)
/* Allow these to be redefined */
#ifndef MMS_LOGLEVEL_MAX
# ifdef DEBUG
# define MMS_LOGLEVEL_MAX MMS_LOGLEVEL_VERBOSE
# else
# define MMS_LOGLEVEL_MAX MMS_LOGLEVEL_DEBUG
# endif
#endif /* MMS_LOGLEVEL_MAX */
#ifndef MMS_LOGLEVEL_DEFAULT
# ifdef DEBUG
# define MMS_LOGLEVEL_DEFAULT MMS_LOGLEVEL_DEBUG
# else
# define MMS_LOGLEVEL_DEFAULT MMS_LOGLEVEL_INFO
# endif
#endif /* MMS_LOGLEVEL_DEFAULT */
/* Do we need a separate log level for ASSERTs? */
#ifndef MMS_LOGLEVEL_ASSERT
# ifdef DEBUG
# define MMS_LOGLEVEL_ASSERT MMS_LOGLEVEL_ERR
# else
/* No asserts in release build */
# define MMS_LOGLEVEL_ASSERT (MMS_LOGLEVEL_MAX+1)
# endif
#endif
/* Log module */
struct mms_log_module {
const char* name;
const int max_level;
int level;
};
/* Command line parsing helper. Option format is [module]:level
* where level can be either a number or log level name ("none", err etc.) */
gboolean
mms_log_parse_option(
const char* opt, /* String to parse */
MMSLogModule** modules, /* Known modules */
int count, /* Number of known modules */
GError** error); /* Optional error message */
/* Set log type by name ("syslog", "stdout" or "glib"). This is also
* primarily for parsing command line options */
gboolean
mms_log_set_type(
const char* type,
const char* default_name);
const char*
mms_log_get_type(
void);
/* Generates the string containg description of log levels and list of
* log modules. The caller must deallocate the string with g_free */
char*
mms_log_description(
MMSLogModule** modules, /* Known modules */
int count); /* Number of known modules */
/* Logging function */
void
mms_log(
const MMSLogModule* module, /* Calling module (NULL for default) */
int level, /* Message log level */
const char* format, /* Message format */
...) G_GNUC_PRINTF(3,4); /* Followed by arguments */
void
mms_logv(
const MMSLogModule* module,
int level,
const char* format,
va_list va);
extern const char MMS_LOG_TYPE_STDOUT[];
extern const char MMS_LOG_TYPE_GLIB[];
extern const char MMS_LOG_TYPE_CUSTOM[];
#ifdef unix
# define MMS_LOG_SYSLOG
extern const char MMS_LOG_TYPE_SYSLOG[];
#endif
/* Available log handlers */
#define MMS_DEFINE_LOG_FN(fn) void fn(const char* name, int level, \
const char* format, va_list va)
MMS_DEFINE_LOG_FN(mms_log_stdout);
MMS_DEFINE_LOG_FN(mms_log_glib);
#ifdef MMS_LOG_SYSLOG
MMS_DEFINE_LOG_FN(mms_log_syslog);
#endif
/* Log configuration */
#define MMS_LOG_MODULE_DECL(m) extern MMSLogModule m;
MMS_LOG_MODULE_DECL(mms_log_default)
typedef MMS_DEFINE_LOG_FN((*MMSLogFunc));
extern MMSLogFunc mms_log_func;
extern gboolean mms_log_stdout_timestamp;
/* Log module (optional) */
#define MMS_LOG_MODULE_DEFINE_(mod,name) \
MMSLogModule mod = {name, \
MMS_LOGLEVEL_MAX, MMS_LOGLEVEL_GLOBAL}
#ifdef MMS_LOG_MODULE_NAME
extern MMSLogModule MMS_LOG_MODULE_NAME;
# define MMS_LOG_MODULE_CURRENT (&MMS_LOG_MODULE_NAME)
# define MMS_LOG_MODULE_DEFINE(name) \
MMS_LOG_MODULE_DEFINE_(MMS_LOG_MODULE_NAME,name)
#else
# define MMS_LOG_MODULE_CURRENT NULL
#endif
/* Logging macros */
#define MMS_LOG_NOTHING ((void)0)
#define MMS_ERRMSG(err) (((err) && (err)->message) ? (err)->message : \
"Unknown error")
#if !defined(MMS_LOG_VARARGS) && defined(__GNUC__)
# define MMS_LOG_VARARGS
#endif
#ifndef MMS_LOG_VARARGS
# define MMS_LOG_VA_NONE(x) static inline void MMS_##x(const char* f, ...) {}
# define MMS_LOG_VA(x) static inline void MMS_##x(const char* f, ...) { \
if (f && f[0]) { \
va_list va; va_start(va,f); \
mms_logv(MMS_LOG_MODULE_CURRENT, MMS_LOGLEVEL_##x, f, va); \
va_end(va); \
} \
}
#endif /* MMS_LOG_VARARGS */
#define MMS_LOG_ENABLED (MMS_LOGLEVEL_MAX >= MMS_LOGLEVEL_NONE)
#define MMS_LOG_ERR (MMS_LOGLEVEL_MAX >= MMS_LOGLEVEL_ERR)
#define MMS_LOG_WARN (MMS_LOGLEVEL_MAX >= MMS_LOGLEVEL_WARN)
#define MMS_LOG_INFO (MMS_LOGLEVEL_MAX >= MMS_LOGLEVEL_INFO)
#define MMS_LOG_DEBUG (MMS_LOGLEVEL_MAX >= MMS_LOGLEVEL_DEBUG)
#define MMS_LOG_VERBOSE (MMS_LOGLEVEL_MAX >= MMS_LOGLEVEL_VERBOSE)
#define MMS_LOG_ASSERT (MMS_LOGLEVEL_MAX >= MMS_LOGLEVEL_ASSERT)
#if MMS_LOG_ASSERT
void
mms_log_assert(
const MMSLogModule* module, /* Calling module (NULL for default) */
const char* expr, /* Assert expression */
const char* file, /* File name */
int line); /* Line number */
# define MMS_ASSERT(expr) ((expr) ? MMS_LOG_NOTHING : \
mms_log_assert(MMS_LOG_MODULE_CURRENT, #expr, __FILE__, __LINE__))
# define MMS_VERIFY(expr) MMS_ASSERT(expr)
#else
# define MMS_ASSERT(expr)
# define MMS_VERIFY(expr) (expr)
#endif
#ifdef MMS_LOG_VARARGS
# if MMS_LOG_ERR
# define MMS_ERR(f,args...) mms_log(MMS_LOG_MODULE_CURRENT, \
MMS_LOGLEVEL_ERR, f, ##args)
# define MMS_ERR_(f,args...) mms_log(MMS_LOG_MODULE_CURRENT, \
MMS_LOGLEVEL_ERR, "%s() " f, __FUNCTION__, ##args)
# else
# define MMS_ERR(f,args...) MMS_LOG_NOTHING
# define MMS_ERR_(f,args...) MMS_LOG_NOTHING
# endif /* MMS_LOG_ERR */
#else
# define MMS_ERR_ MMS_ERR
# if MMS_LOG_ERR
MMS_LOG_VA(ERR)
# else
MMS_LOG_VA_NONE(ERR)
# endif /* MMS_LOG_ERR */
#endif /* MMS_LOG_VARARGS */
#ifdef MMS_LOG_VARARGS
# if MMS_LOG_WARN
# define MMS_WARN(f,args...) mms_log(MMS_LOG_MODULE_CURRENT, \
MMS_LOGLEVEL_WARN, f, ##args)
# define MMS_WARN_(f,args...) mms_log(MMS_LOG_MODULE_CURRENT, \
MMS_LOGLEVEL_WARN, "%s() " f, __FUNCTION__, ##args)
# else
# define MMS_WARN(f,args...) MMS_LOG_NOTHING
# define MMS_WARN_(f,args...) MMS_LOG_NOTHING
# endif /* MMS_LOGL_WARN */
#else
# define MMS_WARN_ MMS_WARN
# if MMS_LOG_WARN
MMS_LOG_VA(WARN)
# else
MMS_LOG_VA_NONE(WARN)
# endif /* MMS_LOGL_WARN */
# endif /* MMS_LOG_VARARGS */
#ifdef MMS_LOG_VARARGS
# if MMS_LOG_INFO
# define MMS_INFO(f,args...) mms_log(MMS_LOG_MODULE_CURRENT, \
MMS_LOGLEVEL_INFO, f, ##args)
# define MMS_INFO_(f,args...) mms_log(MMS_LOG_MODULE_CURRENT, \
MMS_LOGLEVEL_INFO, "%s() " f, __FUNCTION__, ##args)
# else
# define MMS_INFO(f,args...) MMS_LOG_NOTHING
# define MMS_INFO_(f,args...) MMS_LOG_NOTHING
# endif /* MMS_LOG_INFO */
#else
# define MMS_INFO_ MMS_INFO
# if MMS_LOG_INFO
MMS_LOG_VA(INFO)
# else
MMS_LOG_VA_NONE(INFO)
# endif /* MMS_LOG_INFO */
#endif /* MMS_LOG_VARARGS */
#ifdef MMS_LOG_VARARGS
# if MMS_LOG_DEBUG
# define MMS_DEBUG(f,args...) mms_log(MMS_LOG_MODULE_CURRENT, \
MMS_LOGLEVEL_DEBUG, f, ##args)
# define MMS_DEBUG_(f,args...) mms_log(MMS_LOG_MODULE_CURRENT, \
MMS_LOGLEVEL_DEBUG, "%s() " f, __FUNCTION__, ##args)
# else
# define MMS_DEBUG(f,args...) MMS_LOG_NOTHING
# define MMS_DEBUG_(f,args...) MMS_LOG_NOTHING
# endif /* MMS_LOG_DEBUG */
#else
# define MMS_DEBUG_ MMS_DEBUG
# if MMS_LOG_DEBUG
MMS_LOG_VA(DEBUG)
# else
MMS_LOG_VA_NONE(DEBUG)
# endif /* MMS_LOG_DEBUG */
#endif /* MMS_LOG_VARARGS */
#ifdef MMS_LOG_VARARGS
# if MMS_LOG_VERBOSE
# define MMS_VERBOSE(f,args...) mms_log(MMS_LOG_MODULE_CURRENT, \
MMS_LOGLEVEL_VERBOSE, f, ##args)
# define MMS_VERBOSE_(f,args...) mms_log(MMS_LOG_MODULE_CURRENT, \
MMS_LOGLEVEL_VERBOSE, "%s() " f, __FUNCTION__, ##args)
# else
# define MMS_VERBOSE(f,args...) MMS_LOG_NOTHING
# define MMS_VERBOSE_(f,args...) MMS_LOG_NOTHING
# endif /* MMS_LOG_VERBOSE */
#else
# define MMS_VERBOSE_ MMS_VERBOSE
# if MMS_LOG_VERBOSE
MMS_LOG_VA(VERBOSE)
# else
MMS_LOG_VA_NONE(VERBOSE)
# endif /* MMS_LOG_VERBOSE */
#endif /* MMS_LOG_VARARGS */
#endif /* JOLLA_MMS_LOG_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/