2 * lxc: linux Container library
4 * (C) Copyright IBM Corp. 2007, 2008
7 * Cedric Le Goater <legoater@free.fr>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include <sys/types.h>
31 #define __USE_GNU /* for *_CLOEXEC */
39 #define LXC_LOG_PREFIX_SIZE 32
40 #define LXC_LOG_BUFFER_SIZE 512
43 static char log_prefix
[LXC_LOG_PREFIX_SIZE
] = "lxc";
44 static int lxc_loglevel_specified
= 0;
46 lxc_log_define(lxc_log
, lxc
);
48 /*---------------------------------------------------------------------------*/
49 static int log_append_stderr(const struct lxc_log_appender
*appender
,
50 struct lxc_log_event
*event
)
52 if (event
->priority
< LXC_LOG_PRIORITY_ERROR
)
55 fprintf(stderr
, "%s: ", log_prefix
);
56 vfprintf(stderr
, event
->fmt
, *event
->vap
);
57 fprintf(stderr
, "\n");
61 /*---------------------------------------------------------------------------*/
62 static int log_append_logfile(const struct lxc_log_appender
*appender
,
63 struct lxc_log_event
*event
)
65 char buffer
[LXC_LOG_BUFFER_SIZE
];
71 n
= snprintf(buffer
, sizeof(buffer
),
72 "%15s %10ld.%03ld %-8s %s - ",
74 event
->timestamp
.tv_sec
,
75 event
->timestamp
.tv_usec
/ 1000,
76 lxc_log_priority_to_string(event
->priority
),
79 n
+= vsnprintf(buffer
+ n
, sizeof(buffer
) - n
, event
->fmt
,
82 if (n
>= sizeof(buffer
) - 1) {
83 WARN("truncated next event from %d to %zd bytes", n
,
85 n
= sizeof(buffer
) - 1;
90 return write(lxc_log_fd
, buffer
, n
+ 1);
93 static struct lxc_log_appender log_appender_stderr
= {
95 .append
= log_append_stderr
,
99 static struct lxc_log_appender log_appender_logfile
= {
101 .append
= log_append_logfile
,
105 static struct lxc_log_category log_root
= {
107 .priority
= LXC_LOG_PRIORITY_ERROR
,
112 struct lxc_log_category lxc_log_category_lxc
= {
114 .priority
= LXC_LOG_PRIORITY_ERROR
,
115 .appender
= &log_appender_stderr
,
119 /*---------------------------------------------------------------------------*/
120 extern void lxc_log_setprefix(const char *prefix
)
122 strncpy(log_prefix
, prefix
, sizeof(log_prefix
));
123 log_prefix
[sizeof(log_prefix
) - 1] = 0;
126 /*---------------------------------------------------------------------------*/
127 static int log_open(const char *name
)
132 fd
= lxc_unpriv(open(name
, O_CREAT
| O_WRONLY
|
133 O_APPEND
| O_CLOEXEC
, 0666));
135 ERROR("failed to open log file \"%s\" : %s", name
,
143 newfd
= fcntl(fd
, F_DUPFD_CLOEXEC
, 3);
145 ERROR("failed to dup log fd %d : %s", fd
, strerror(errno
));
151 /*---------------------------------------------------------------------------*/
152 extern int lxc_log_init(const char *file
, const char *priority
,
153 const char *prefix
, int quiet
)
155 int lxc_priority
= LXC_LOG_PRIORITY_ERROR
;
157 if (lxc_log_fd
!= -1)
161 lxc_loglevel_specified
= 1;
162 lxc_priority
= lxc_log_priority_to_int(priority
);
164 if (lxc_priority
== LXC_LOG_PRIORITY_NOTSET
) {
165 ERROR("invalid log priority %s", priority
);
170 lxc_log_category_lxc
.priority
= lxc_priority
;
171 lxc_log_category_lxc
.appender
= &log_appender_logfile
;
174 lxc_log_category_lxc
.appender
->next
= &log_appender_stderr
;
177 lxc_log_setprefix(prefix
);
180 return lxc_log_set_file(file
);
186 * This is called when we read a lxc.loglevel entry in a lxc.conf file. This
187 * happens after processing command line arguments, which override the .conf
188 * settings. So only set the level if previously unset.
190 extern int lxc_log_set_level(int level
)
192 if (lxc_loglevel_specified
)
194 if (level
< 0 || level
>= LXC_LOG_PRIORITY_NOTSET
) {
195 ERROR("invalid log priority %d", level
);
198 lxc_log_category_lxc
.priority
= level
;
202 char *log_fname
; // default to NULL, set in lxc_log_set_file.
205 * This is called when we read a lxc.logfile entry in a lxc.conf file. This
206 * happens after processing command line arguments, which override the .conf
207 * settings. So only set the logfile if previously unset.
209 extern int lxc_log_set_file(const char *fname
)
211 if (lxc_log_fd
!= -1) {
212 // this should've been caught at config_logfile.
213 ERROR("Race in setting logfile?");
217 lxc_log_fd
= log_open(fname
);
218 if (lxc_log_fd
== -1) {
219 ERROR("failed to open log file %s\n", fname
);
223 log_fname
= strdup(fname
);
227 extern int lxc_log_get_level(void)
229 if (!lxc_loglevel_specified
)
230 return LXC_LOG_PRIORITY_NOTSET
;
231 return lxc_log_category_lxc
.priority
;
234 extern const char *lxc_log_get_file(void)