2
* lxc: linux Container library
4
* (C) Copyright IBM Corp. 2007, 2008
7
* Daniel Lezcano <dlezcano at fr.ibm.com>
8
* Cedric Le Goater <legoater@free.fr>
10
* This library is free software; you can redistribute it and/or
11
* modify it under the terms of the GNU Lesser General Public
12
* License as published by the Free Software Foundation; either
13
* version 2.1 of the License, or (at your option) any later version.
15
* This library is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18
* Lesser General Public License for more details.
20
* You should have received a copy of the GNU Lesser General Public
21
* License along with this library; if not, write to the Free Software
22
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33
#define O_CLOEXEC 02000000
36
#ifndef F_DUPFD_CLOEXEC
37
#define F_DUPFD_CLOEXEC 1030
40
#define LXC_LOG_PREFIX_SIZE 32
41
#define LXC_LOG_BUFFER_SIZE 512
43
/* predefined priorities. */
45
LXC_LOG_PRIORITY_TRACE,
46
LXC_LOG_PRIORITY_DEBUG,
47
LXC_LOG_PRIORITY_INFO,
48
LXC_LOG_PRIORITY_NOTICE,
49
LXC_LOG_PRIORITY_WARN,
50
LXC_LOG_PRIORITY_ERROR,
51
LXC_LOG_PRIORITY_CRIT,
52
LXC_LOG_PRIORITY_ALERT,
53
LXC_LOG_PRIORITY_FATAL,
54
LXC_LOG_PRIORITY_NOTSET,
57
/* location information of the logging event */
58
struct lxc_log_locinfo {
64
#define LXC_LOG_LOCINFO_INIT \
65
{ .file = __FILE__, .func = __func__, .line = __LINE__ }
67
/* brief logging event object */
68
struct lxc_log_event {
71
struct timeval timestamp;
72
struct lxc_log_locinfo *locinfo;
77
/* log appender object */
78
struct lxc_log_appender {
80
int (*append)(const struct lxc_log_appender *,
81
const struct lxc_log_event *);
84
* appenders can be stacked
86
struct lxc_log_appender *next;
89
/* log category object */
90
struct lxc_log_category {
93
struct lxc_log_appender *appender;
94
const struct lxc_log_category *parent;
98
* Returns true if the chained priority is equal to or higher than
102
lxc_log_priority_is_enabled(const struct lxc_log_category* category,
105
while (category->priority == LXC_LOG_PRIORITY_NOTSET &&
107
category = category->parent;
109
return priority >= category->priority;
113
* converts a priority to a literal string
115
static inline const char* lxc_log_priority_to_string(int priority)
118
case LXC_LOG_PRIORITY_TRACE: return "TRACE";
119
case LXC_LOG_PRIORITY_DEBUG: return "DEBUG";
120
case LXC_LOG_PRIORITY_INFO: return "INFO";
121
case LXC_LOG_PRIORITY_NOTICE: return "NOTICE";
122
case LXC_LOG_PRIORITY_WARN: return "WARN";
123
case LXC_LOG_PRIORITY_ERROR: return "ERROR";
124
case LXC_LOG_PRIORITY_CRIT: return "CRIT";
125
case LXC_LOG_PRIORITY_ALERT: return "ALERT";
126
case LXC_LOG_PRIORITY_FATAL: return "FATAL";
132
* converts a literal priority to an int
134
static inline int lxc_log_priority_to_int(const char* name)
136
if (!strcasecmp("TRACE", name)) return LXC_LOG_PRIORITY_TRACE;
137
if (!strcasecmp("DEBUG", name)) return LXC_LOG_PRIORITY_DEBUG;
138
if (!strcasecmp("INFO", name)) return LXC_LOG_PRIORITY_INFO;
139
if (!strcasecmp("NOTICE", name)) return LXC_LOG_PRIORITY_NOTICE;
140
if (!strcasecmp("WARN", name)) return LXC_LOG_PRIORITY_WARN;
141
if (!strcasecmp("ERROR", name)) return LXC_LOG_PRIORITY_ERROR;
142
if (!strcasecmp("CRIT", name)) return LXC_LOG_PRIORITY_CRIT;
143
if (!strcasecmp("ALERT", name)) return LXC_LOG_PRIORITY_ALERT;
144
if (!strcasecmp("FATAL", name)) return LXC_LOG_PRIORITY_FATAL;
146
return LXC_LOG_PRIORITY_NOTSET;
150
__lxc_log_append(const struct lxc_log_appender *appender,
151
const struct lxc_log_event* event)
154
appender->append(appender, event);
155
appender = appender->next;
160
__lxc_log(const struct lxc_log_category* category,
161
const struct lxc_log_event* event)
164
__lxc_log_append(category->appender, event);
165
category = category->parent;
170
* Helper macro to define log fonctions.
172
#define lxc_log_priority_define(acategory, PRIORITY) \
174
static inline void LXC_##PRIORITY(struct lxc_log_locinfo *, \
175
const char *, ...) __attribute__ ((format (printf, 2, 3))); \
177
static inline void LXC_##PRIORITY(struct lxc_log_locinfo* locinfo, \
178
const char* format, ...) \
180
if (lxc_log_priority_is_enabled(acategory, \
181
LXC_LOG_PRIORITY_##PRIORITY)) { \
182
struct lxc_log_event evt = { \
183
.category = (acategory)->name, \
184
.priority = LXC_LOG_PRIORITY_##PRIORITY, \
189
gettimeofday(&evt.timestamp, NULL); \
191
va_start(evt.va, format); \
192
__lxc_log(acategory, &evt); \
198
* Helper macro to define and use static categories.
200
#define lxc_log_category_define(name, parent) \
201
extern struct lxc_log_category lxc_log_category_##parent; \
202
struct lxc_log_category lxc_log_category_##name = { \
204
LXC_LOG_PRIORITY_NOTSET, \
206
&lxc_log_category_##parent \
209
#define lxc_log_define(name, parent) \
210
lxc_log_category_define(name, parent) \
212
lxc_log_priority_define(&lxc_log_category_##name, TRACE) \
213
lxc_log_priority_define(&lxc_log_category_##name, DEBUG) \
214
lxc_log_priority_define(&lxc_log_category_##name, INFO) \
215
lxc_log_priority_define(&lxc_log_category_##name, NOTICE) \
216
lxc_log_priority_define(&lxc_log_category_##name, WARN) \
217
lxc_log_priority_define(&lxc_log_category_##name, ERROR) \
218
lxc_log_priority_define(&lxc_log_category_##name, CRIT) \
219
lxc_log_priority_define(&lxc_log_category_##name, ALERT) \
220
lxc_log_priority_define(&lxc_log_category_##name, FATAL)
222
#define lxc_log_category_priority(name) \
223
(lxc_log_priority_to_string(lxc_log_category_##name.priority))
228
extern struct lxc_log_category lxc_log_category_lxc;
230
#define TRACE(format, ...) do { \
231
struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
232
LXC_TRACE(&locinfo, format, ##__VA_ARGS__); \
235
#define DEBUG(format, ...) do { \
236
struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
237
LXC_DEBUG(&locinfo, format, ##__VA_ARGS__); \
240
#define INFO(format, ...) do { \
241
struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
242
LXC_INFO(&locinfo, format, ##__VA_ARGS__); \
245
#define NOTICE(format, ...) do { \
246
struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
247
LXC_NOTICE(&locinfo, format, ##__VA_ARGS__); \
250
#define WARN(format, ...) do { \
251
struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
252
LXC_WARN(&locinfo, format, ##__VA_ARGS__); \
255
#define ERROR(format, ...) do { \
256
struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
257
LXC_ERROR(&locinfo, format, ##__VA_ARGS__); \
260
#define CRIT(format, ...) do { \
261
struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
262
LXC_CRIT(&locinfo, format, ##__VA_ARGS__); \
265
#define ALERT(format, ...) do { \
266
struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
267
LXC_ALERT(&locinfo, format, ##__VA_ARGS__); \
270
#define FATAL(format, ...) do { \
271
struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
272
LXC_FATAL(&locinfo, format, ##__VA_ARGS__); \
277
#define SYSERROR(format, ...) do { \
278
ERROR("%s - " format "\n", strerror(errno), ##__VA_ARGS__); \