]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/log.c
Revert "use a default per-container logfile"
[mirror_lxc.git] / src / lxc / log.c
CommitLineData
e0b4037d
DL
1/*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
7 * Cedric Le Goater <legoater@free.fr>
8 *
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.
13 *
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.
18 *
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
22 */
0ad19a3f 23#include <stdio.h>
24#include <errno.h>
cb8c5720
CLG
25#include <limits.h>
26#include <unistd.h>
27#include <sys/types.h>
28#include <sys/stat.h>
29#include <string.h>
30
31#define __USE_GNU /* for *_CLOEXEC */
32
33#include <fcntl.h>
34#include <stdlib.h>
35
28f602ff
DL
36#include "log.h"
37#include "caps.h"
cb8c5720 38
6b9f3917
DL
39#define LXC_LOG_PREFIX_SIZE 32
40#define LXC_LOG_BUFFER_SIZE 512
41
d737c074 42int lxc_log_fd = -1;
6b9f3917 43static char log_prefix[LXC_LOG_PREFIX_SIZE] = "lxc";
9ea87d5d 44static int lxc_loglevel_specified = 0;
cb8c5720
CLG
45
46lxc_log_define(lxc_log, lxc);
47
d737c074
MN
48/*---------------------------------------------------------------------------*/
49static int log_append_stderr(const struct lxc_log_appender *appender,
50 struct lxc_log_event *event)
51{
52 if (event->priority < LXC_LOG_PRIORITY_ERROR)
53 return 0;
54
55 fprintf(stderr, "%s: ", log_prefix);
56 vfprintf(stderr, event->fmt, *event->vap);
57 fprintf(stderr, "\n");
58 return 0;
59}
60
cb8c5720
CLG
61/*---------------------------------------------------------------------------*/
62static int log_append_logfile(const struct lxc_log_appender *appender,
5fd8380b 63 struct lxc_log_event *event)
cb8c5720
CLG
64{
65 char buffer[LXC_LOG_BUFFER_SIZE];
66 int n;
67
68 if (lxc_log_fd == -1)
69 return 0;
70
71 n = snprintf(buffer, sizeof(buffer),
72 "%15s %10ld.%03ld %-8s %s - ",
73 log_prefix,
74 event->timestamp.tv_sec,
75 event->timestamp.tv_usec / 1000,
76 lxc_log_priority_to_string(event->priority),
77 event->category);
78
79 n += vsnprintf(buffer + n, sizeof(buffer) - n, event->fmt,
5fd8380b 80 *event->vap);
cb8c5720
CLG
81
82 if (n >= sizeof(buffer) - 1) {
5fd8380b 83 WARN("truncated next event from %d to %zd bytes", n,
cb8c5720
CLG
84 sizeof(buffer));
85 n = sizeof(buffer) - 1;
86 }
87
88 buffer[n] = '\n';
89
90 return write(lxc_log_fd, buffer, n + 1);
91}
92
d737c074
MN
93static struct lxc_log_appender log_appender_stderr = {
94 .name = "stderr",
95 .append = log_append_stderr,
96 .next = NULL,
97};
98
cb8c5720
CLG
99static struct lxc_log_appender log_appender_logfile = {
100 .name = "logfile",
101 .append = log_append_logfile,
441e4963 102 .next = NULL,
cb8c5720
CLG
103};
104
105static struct lxc_log_category log_root = {
106 .name = "root",
107 .priority = LXC_LOG_PRIORITY_ERROR,
108 .appender = NULL,
109 .parent = NULL,
110};
111
112struct lxc_log_category lxc_log_category_lxc = {
113 .name = "lxc",
114 .priority = LXC_LOG_PRIORITY_ERROR,
25df6b78 115 .appender = &log_appender_stderr,
cb8c5720
CLG
116 .parent = &log_root
117};
118
119/*---------------------------------------------------------------------------*/
120extern void lxc_log_setprefix(const char *prefix)
121{
122 strncpy(log_prefix, prefix, sizeof(log_prefix));
123 log_prefix[sizeof(log_prefix) - 1] = 0;
124}
125
126/*---------------------------------------------------------------------------*/
127static int log_open(const char *name)
128{
129 int fd;
130 int newfd;
131
28f602ff
DL
132 fd = lxc_unpriv(open(name, O_CREAT | O_WRONLY |
133 O_APPEND | O_CLOEXEC, 0666));
cb8c5720
CLG
134 if (fd == -1) {
135 ERROR("failed to open log file \"%s\" : %s", name,
136 strerror(errno));
137 return -1;
138 }
139
140 if (fd > 2)
141 return fd;
142
143 newfd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
144 if (newfd == -1)
145 ERROR("failed to dup log fd %d : %s", fd, strerror(errno));
146
147 close(fd);
148 return newfd;
149}
150
151/*---------------------------------------------------------------------------*/
e6cde741
SG
152extern int lxc_log_init(const char *file, const char *priority,
153 const char *prefix, int quiet)
cb8c5720 154{
51cab631
MN
155 int lxc_priority = LXC_LOG_PRIORITY_ERROR;
156
2312f31b
DE
157 if (lxc_log_fd != -1)
158 return 0;
159
51cab631 160 if (priority) {
4a85ce2a 161 lxc_loglevel_specified = 1;
51cab631
MN
162 lxc_priority = lxc_log_priority_to_int(priority);
163
164 if (lxc_priority == LXC_LOG_PRIORITY_NOTSET) {
165 ERROR("invalid log priority %s", priority);
166 return -1;
167 }
168 }
169
170 lxc_log_category_lxc.priority = lxc_priority;
25df6b78 171 lxc_log_category_lxc.appender = &log_appender_logfile;
cb8c5720 172
441e4963
MN
173 if (!quiet)
174 lxc_log_category_lxc.appender->next = &log_appender_stderr;
175
cb8c5720
CLG
176 if (prefix)
177 lxc_log_setprefix(prefix);
178
e6cde741
SG
179 if (file)
180 return lxc_log_set_file(file);
74476cf1 181
e6cde741 182 return 0;
cb8c5720 183}
4a85ce2a
SH
184
185/*
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.
189 */
190extern int lxc_log_set_level(int level)
191{
192 if (lxc_loglevel_specified)
193 return 0;
194 if (level < 0 || level >= LXC_LOG_PRIORITY_NOTSET) {
195 ERROR("invalid log priority %d", level);
196 return -1;
197 }
198 lxc_log_category_lxc.priority = level;
199 return 0;
200}
201
9ea87d5d
SH
202char *log_fname; // default to NULL, set in lxc_log_set_file.
203
4a85ce2a 204/*
e6cde741
SG
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.
4a85ce2a 208 */
9ea87d5d 209extern int lxc_log_set_file(const char *fname)
4a85ce2a
SH
210{
211 if (lxc_log_fd != -1) {
e6cde741
SG
212 // this should've been caught at config_logfile.
213 ERROR("Race in setting logfile?");
214 return -1;
4a85ce2a 215 }
9ea87d5d 216
4a85ce2a
SH
217 lxc_log_fd = log_open(fname);
218 if (lxc_log_fd == -1) {
219 ERROR("failed to open log file %s\n", fname);
220 return -1;
221 }
9ea87d5d
SH
222
223 log_fname = strdup(fname);
4a85ce2a
SH
224 return 0;
225}
9ea87d5d
SH
226
227extern int lxc_log_get_level(void)
228{
229 if (!lxc_loglevel_specified)
230 return LXC_LOG_PRIORITY_NOTSET;
231 return lxc_log_category_lxc.priority;
232}
233
234extern const char *lxc_log_get_file(void)
235{
236 return log_fname;
237}