log.c revision 8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71c
566f735e84e576e1592d0bf367182a0586944380Robert Wapshott/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
566f735e84e576e1592d0bf367182a0586944380Robert Wapshott This file is part of systemd.
along with systemd; If not, see <http://www.gnu.org/licenses/>.
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <limits.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "sd-messages.h"
#include "alloc-util.h"
#include "fd-util.h"
#include "formats-util.h"
#include "io-util.h"
#include "log.h"
#include "macro.h"
#include "missing.h"
#include "parse-util.h"
#include "proc-cmdline.h"
#include "process-util.h"
#include "signal-util.h"
#include "socket-util.h"
#include "stdio-util.h"
#include "string-table.h"
#include "string-util.h"
#include "syslog-util.h"
#include "terminal-util.h"
#include "time-util.h"
#include "util.h"
static bool syslog_is_stream = false;
static bool show_color = false;
static bool show_location = false;
static bool upgrade_syslog_to_journal = false;
void log_close_console(void) {
if (console_fd < 0)
static int log_open_console(void) {
if (console_fd >= 0)
if (console_fd < 0)
return console_fd;
void log_close_kmsg(void) {
static int log_open_kmsg(void) {
if (kmsg_fd >= 0)
if (kmsg_fd < 0)
return -errno;
void log_close_syslog(void) {
int fd;
if (fd < 0)
return -errno;
return fd;
static int log_open_syslog(void) {
if (syslog_fd >= 0)
if (syslog_fd < 0) {
r = syslog_fd;
goto fail;
if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
if (syslog_fd < 0) {
r = syslog_fd;
goto fail;
if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
r = -errno;
goto fail;
syslog_is_stream = true;
syslog_is_stream = false;
fail:
void log_close_journal(void) {
static int log_open_journal(void) {
if (journal_fd >= 0)
if (journal_fd < 0) {
r = journal_fd;
goto fail;
if (connect(journal_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
r = -errno;
goto fail;
fail:
int log_open(void) {
r = log_open_journal();
r = log_open_syslog();
r = log_open_kmsg();
return log_open_console();
if (upgrade_syslog_to_journal) {
void log_close(void) {
void log_forget_fds(void) {
static int write_to_console(
int level,
int error,
const char *file,
int line,
const char *func,
const char *object_field,
const char *object,
const char *buffer) {
bool highlight;
if (console_fd < 0)
if (show_location) {
if (highlight)
if (highlight)
if (console_fd < 0)
return -errno;
return -errno;
static int write_to_syslog(
int level,
int error,
const char *file,
int line,
const char *func,
const char *object_field,
const char *object,
const char *buffer) {
time_t t;
if (syslog_fd < 0)
if (!tm)
return -EINVAL;
return -EINVAL;
if (syslog_is_stream)
ssize_t n;
return -errno;
if (!syslog_is_stream ||
static int write_to_kmsg(
int level,
int error,
const char *file,
int line,
const char *func,
const char *object_field,
const char *object,
const char *buffer) {
if (kmsg_fd < 0)
return -errno;
static int log_do_header(
char *header,
int level,
int error,
static int write_to_journal(
int level,
int error,
const char *file,
int line,
const char *func,
const char *object_field,
const char *object,
const char *buffer) {
if (journal_fd < 0)
return -errno;
static int log_dispatch(
int level,
int error,
const char *file,
int line,
const char *func,
const char *object_field,
const char *object,
char *buffer) {
return -error;
if (error < 0)
if (buffer[0] == 0)
if (k != -EAGAIN)
if (k != -EAGAIN)
buffer = e;
} while (buffer);
return -error;
int log_dump_internal(
int level,
int error,
const char *file,
int line,
const char *func,
char *buffer) {
if (error < 0)
return -error;
int log_internalv(
int level,
int error,
const char *file,
int line,
const char *func,
const char *format,
if (error < 0)
return -error;
if (error != 0)
int log_internal(
int level,
int error,
const char *file,
int line,
const char *func,
const char *format, ...) {
int log_object_internalv(
int level,
int error,
const char *file,
int line,
const char *func,
const char *object_field,
const char *object,
const char *format,
char *buffer, *b;
size_t l;
if (error < 0)
return -error;
if (error != 0)
if (object) {
size_t n;
l = LINE_MAX;
int log_object_internal(
int level,
int error,
const char *file,
int line,
const char *func,
const char *object_field,
const char *object,
const char *format, ...) {
static void log_assert(
int level,
const char *text,
const char *file,
int line,
const char *func,
const char *format) {
log_assert(LOG_CRIT, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
abort();
noreturn void log_assert_failed_unreachable(const char *text, const char *file, int line, const char *func) {
log_assert(LOG_CRIT, text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
abort();
log_assert(LOG_DEBUG, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
return -ENOMEM;
int log_format_iovec(
unsigned iovec_len,
bool newline_separator,
int error,
const char *format,
if (error != 0)
return -EINVAL;
if (newline_separator) {
int log_struct_internal(
int level,
int error,
const char *file,
int line,
const char *func,
const char *format, ...) {
bool found = false;
if (error < 0)
return -error;
return -error;
journal_fd >= 0) {
bool fallback = false;
fallback = true;
if (!fallback)
return -error;
while (format) {
if (error != 0)
found = true;
if (!found)
return -error;
int log_set_target_from_string(const char *e) {
LogTarget t;
t = log_target_from_string(e);
return -EINVAL;
log_set_target(t);
int log_set_max_level_from_string(const char *e) {
t = log_level_from_string(e);
return -EINVAL;
void log_parse_environment(void) {
if (e && log_set_target_from_string(e) < 0)
if (e && log_set_max_level_from_string(e) < 0)
if (e && log_show_color_from_string(e) < 0)
if (e && log_show_location_from_string(e) < 0)
return log_target;
int log_get_max_level(void) {
return log_max_level;
void log_show_color(bool b) {
show_color = b;
bool log_get_show_color(void) {
return show_color;
void log_show_location(bool b) {
show_location = b;
bool log_get_show_location(void) {
return show_location;
int log_show_color_from_string(const char *e) {
t = parse_boolean(e);
log_show_color(t);
int log_show_location_from_string(const char *e) {
t = parse_boolean(e);
bool log_on_console(void) {
void log_set_upgrade_syslog_to_journal(bool b) {
int log_syntax_internal(
const char *unit,
int level,
const char *config_file,
unsigned config_line,
int error,
const char *file,
int line,
const char *func,
const char *format, ...) {
if (error < 0)
return -error;
return -error;
if (error != 0)
if (unit)
r = log_struct_internal(
NULL);
r = log_struct_internal(
NULL);