31
34
#include <unistd.h>
43
#define G_LOG_DOMAIN "log"
36
45
#define LOG_LEVEL_SECURE G_LOG_LEVEL_INFO
38
47
#define LOG_DATE_BUF_SIZE 16
39
48
#define LOG_DATE_LEN (LOG_DATE_BUF_SIZE - 1)
41
static unsigned int log_threshold = G_LOG_LEVEL_MESSAGE;
50
static GLogLevelFlags log_threshold = G_LOG_LEVEL_MESSAGE;
43
52
static const char *log_charset;
45
54
static bool stdout_mode = true;
46
static int out_fd = -1;
47
static int err_fd = -1;
48
56
static const char *out_filename;
49
static const char *err_filename;
51
static void redirect_logs(void)
58
static void redirect_logs(int fd)
55
if (dup2(out_fd, STDOUT_FILENO) < 0)
56
FATAL("problems dup2 stdout : %s\n", strerror(errno));
57
if (dup2(err_fd, STDERR_FILENO) < 0)
58
FATAL("problems dup2 stderr : %s\n", strerror(errno));
61
if (dup2(fd, STDOUT_FILENO) < 0)
62
g_error("problems dup2 stdout : %s\n", strerror(errno));
63
if (dup2(fd, STDERR_FILENO) < 0)
64
g_error("problems dup2 stderr : %s\n", strerror(errno));
61
67
static const char *log_date(void)
113
117
g_free(converted);
116
void initLog(bool verbose)
121
log_init_stdout(void)
123
g_log_set_default_handler(file_log_func, NULL);
129
assert(out_filename != NULL);
131
return open(out_filename, O_CREAT | O_WRONLY | O_APPEND, 0666);
135
log_init_file(const char *path, unsigned line)
138
out_fd = open_log_file();
140
g_error("problem opening log file \"%s\" (config line %u) for "
141
"writing\n", path, line);
143
g_log_set_default_handler(file_log_func, NULL);
149
glib_to_syslog_level(GLogLevelFlags log_level)
151
switch (log_level & G_LOG_LEVEL_MASK) {
152
case G_LOG_LEVEL_ERROR:
153
case G_LOG_LEVEL_CRITICAL:
156
case G_LOG_LEVEL_WARNING:
159
case G_LOG_LEVEL_MESSAGE:
162
case G_LOG_LEVEL_INFO:
165
case G_LOG_LEVEL_DEBUG:
174
syslog_log_func(const gchar *log_domain,
175
GLogLevelFlags log_level, const gchar *message,
176
G_GNUC_UNUSED gpointer user_data)
179
/* fall back to the file log function during
181
file_log_func(log_domain, log_level,
186
if (log_level > log_threshold)
189
if (log_domain == NULL)
192
syslog(glib_to_syslog_level(log_level), "%s%s%.*s",
193
log_domain, *log_domain == 0 ? "" : ": ",
194
chomp_length(message), message);
198
log_init_syslog(void)
200
assert(out_filename == NULL);
202
openlog(PACKAGE, 0, LOG_DAEMON);
203
g_log_set_default_handler(syslog_log_func, NULL);
208
static inline GLogLevelFlags
209
parse_log_level(const char *value, unsigned line)
211
if (0 == strcmp(value, "default"))
212
return G_LOG_LEVEL_MESSAGE;
213
if (0 == strcmp(value, "secure"))
214
return LOG_LEVEL_SECURE;
215
else if (0 == strcmp(value, "verbose"))
216
return G_LOG_LEVEL_DEBUG;
218
g_error("unknown log level \"%s\" at line %u\n",
220
return G_LOG_LEVEL_MESSAGE;
225
log_early_init(bool verbose)
228
log_threshold = G_LOG_LEVEL_DEBUG;
233
void log_init(bool verbose, bool use_stdout)
235
const struct config_param *param;
120
237
g_get_charset(&log_charset);
122
g_log_set_default_handler(mpd_log_func, NULL);
124
/* unbuffer stdout, stderr is unbuffered by default, leave it */
125
setvbuf(stdout, (char *)NULL, _IONBF, 0);
128
log_threshold = G_LOG_LEVEL_DEBUG;
131
if (!(param = getConfigParam(CONF_LOG_LEVEL)))
133
if (0 == strcmp(param->value, "default")) {
134
log_threshold = G_LOG_LEVEL_MESSAGE;
135
} else if (0 == strcmp(param->value, "secure")) {
136
log_threshold = LOG_LEVEL_SECURE;
137
} else if (0 == strcmp(param->value, "verbose")) {
138
log_threshold = G_LOG_LEVEL_DEBUG;
240
log_threshold = G_LOG_LEVEL_DEBUG;
241
else if ((param = config_get_param(CONF_LOG_LEVEL)) != NULL)
242
log_threshold = parse_log_level(param->value, param->line);
140
FATAL("unknown log level \"%s\" at line %i\n",
141
param->value, param->line);
247
param = config_get_param(CONF_LOG_FILE);
250
/* no configuration: default to syslog (if
254
g_error("config parameter \"%s\" not found\n",
258
} else if (strcmp(param->value, "syslog") == 0) {
262
const char *path = config_get_path(CONF_LOG_FILE);
263
assert(path != NULL);
265
log_init_file(path, param->line);
145
void open_log_files(bool use_stdout)
154
param = parseConfigFilePath(CONF_LOG_FILE, 1);
155
out_filename = param->value;
156
out_fd = open(out_filename, O_CREAT | O_WRONLY | O_APPEND, 0666);
158
FATAL("problem opening log file \"%s\" (config line %i) for "
159
"writing\n", param->value, param->line);
161
param = parseConfigFilePath(CONF_ERROR_FILE, 1);
162
err_filename = param->value;
163
err_fd = open(err_filename, O_CREAT | O_WRONLY | O_APPEND, 0666);
165
FATAL("problem opening error file \"%s\" (config line %i) for "
166
"writing\n", param->value, param->line);
171
270
void setup_log_output(bool use_stdout)
174
273
if (!use_stdout) {
274
if (out_filename != NULL) {
275
redirect_logs(out_fd);
176
279
stdout_mode = false;
177
280
log_charset = NULL;
181
#define log_func(func,level) \
182
G_GNUC_PRINTF(1, 2) void func(const char *fmt, ...) \
184
if (level <= (int)log_threshold) { \
186
va_start(args, fmt); \
187
g_logv(NULL, level, fmt, args); \
192
log_func(ERROR, G_LOG_LEVEL_WARNING)
193
log_func(WARNING, G_LOG_LEVEL_WARNING)
194
log_func(LOG, G_LOG_LEVEL_MESSAGE)
195
log_func(SECURE, LOG_LEVEL_SECURE)
196
log_func(DEBUG, G_LOG_LEVEL_DEBUG)
200
G_GNUC_PRINTF(1, 2) G_GNUC_NORETURN void FATAL(const char *fmt, ...)
204
g_logv(NULL, G_LOG_LEVEL_ERROR, fmt, args);
209
284
int cycle_log_files(void)
288
if (stdout_mode || out_filename == NULL)
215
290
assert(out_filename);
216
assert(err_filename);
218
DEBUG("Cycling log files...\n");
292
g_debug("Cycling log files...\n");
219
293
close_log_files();
223
out_fd = open(out_filename, O_CREAT | O_WRONLY | O_APPEND, 0666);
225
ERROR("error re-opening log file: %s\n", out_filename);
229
err_fd = open(err_filename, O_CREAT | O_WRONLY | O_APPEND, 0666);
231
ERROR("error re-opening error file: %s\n", err_filename);
238
DEBUG("Done cycling log files\n");
295
fd = open_log_file();
297
g_warning("error re-opening log file: %s\n", out_filename);
302
g_debug("Done cycling log files\n");