log.c revision d7832d2c6e0ef5f2839a2296c1cc2fc85c7d9632
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering/***
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering This file is part of systemd.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Copyright 2010 Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering systemd is free software; you can redistribute it and/or modify it
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering under the terms of the GNU General Public License as published by
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering the Free Software Foundation; either version 2 of the License, or
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering (at your option) any later version.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering systemd is distributed in the hope that it will be useful, but
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering General Public License for more details.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering You should have received a copy of the GNU General Public License
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering***/
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include <stdarg.h>
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include <stdio.h>
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include <errno.h>
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include <unistd.h>
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include <fcntl.h>
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include <sys/socket.h>
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include <sys/un.h>
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include <stddef.h>
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "log.h"
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack#include "util.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "macro.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "socket-util.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#define SNDBUF_SIZE (8*1024*1024)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic LogTarget log_target = LOG_TARGET_CONSOLE;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int log_max_level = LOG_INFO;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int log_facility = LOG_DAEMON;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int console_fd = STDERR_FILENO;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int syslog_fd = -1;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int kmsg_fd = -1;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int journal_fd = -1;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poetteringstatic bool syslog_is_stream = false;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic bool show_color = false;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic bool show_location = false;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering/* Akin to glibc's __abort_msg; which is private and we hence cannot
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * use here. */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic char *log_abort_msg = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringvoid log_close_console(void) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (console_fd < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering if (getpid() == 1) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (console_fd >= 3)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering close_nointr_nofail(console_fd);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering console_fd = -1;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int log_open_console(void) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (console_fd >= 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (getpid() == 1) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering console_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (console_fd < 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_error("Failed to open /dev/console for logging: %s", strerror(-console_fd));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return console_fd;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_debug("Successfully opened /dev/console for logging.");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering } else
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering console_fd = STDERR_FILENO;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringvoid log_close_kmsg(void) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (kmsg_fd < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering close_nointr_nofail(kmsg_fd);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering kmsg_fd = -1;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int log_open_kmsg(void) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack if (kmsg_fd >= 0)
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack return 0;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC);
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack if (kmsg_fd < 0) {
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack log_error("Failed to open /dev/kmsg for logging: %s", strerror(errno));
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack return -errno;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack }
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack log_debug("Successfully opened /dev/kmsg for logging.");
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringvoid log_close_syslog(void) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (syslog_fd < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering close_nointr_nofail(syslog_fd);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering syslog_fd = -1;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int create_log_socket(int type) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int fd;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* All output to the syslog/journal fds we do asynchronously,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * and if the buffers are full we just drop the messages */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering fd = socket(AF_UNIX, type|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (fd < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return -errno;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering fd_inc_sndbuf(fd, SNDBUF_SIZE);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return fd;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int log_open_syslog(void) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering union sockaddr_union sa;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (syslog_fd >= 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering zero(sa);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sa.un.sun_family = AF_UNIX;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering strncpy(sa.un.sun_path, "/dev/log", sizeof(sa.un.sun_path));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering syslog_fd = create_log_socket(SOCK_DGRAM);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (syslog_fd < 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = syslog_fd;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto fail;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering close_nointr_nofail(syslog_fd);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* Some legacy syslog systems still use stream
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * sockets. They really shouldn't. But what can we
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * do... */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering syslog_fd = create_log_socket(SOCK_STREAM);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (syslog_fd < 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = syslog_fd;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto fail;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = -errno;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto fail;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering syslog_is_stream = true;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering } else
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering syslog_is_stream = false;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_debug("Successfully opened syslog for logging.");
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack return 0;
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringfail:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_close_syslog();
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering log_debug("Failed to open syslog for logging: %s", strerror(-r));
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack return r;
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringvoid log_close_journal(void) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (journal_fd < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering close_nointr_nofail(journal_fd);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering journal_fd = -1;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int log_open_journal(void) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering union sockaddr_union sa;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (journal_fd >= 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
16ac401407959cbc62312e61c2dd76dbc3a0793bLennart Poettering journal_fd = create_log_socket(SOCK_DGRAM);
16ac401407959cbc62312e61c2dd76dbc3a0793bLennart Poettering if (journal_fd < 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = journal_fd;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto fail;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering zero(sa);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sa.un.sun_family = AF_UNIX;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering strncpy(sa.un.sun_path, "/run/systemd/journal/socket", sizeof(sa.un.sun_path));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (connect(journal_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = -errno;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto fail;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_debug("Successfully opened journal for logging.");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poetteringfail:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_close_journal();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_debug("Failed to open journal for logging: %s", strerror(-r));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringint log_open(void) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* If we don't use the console we close it here, to not get
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * killed by SAK. If we don't use syslog we close it here so
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * that we are not confused by somebody deleting the socket in
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * the fs. If we don't use /dev/kmsg we still keep it open,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * because there is no reason to close it. */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (log_target == LOG_TARGET_NULL) {
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering log_close_journal();
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering log_close_syslog();
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack log_close_console();
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (log_target != LOG_TARGET_AUTO ||
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering getpid() == 1 ||
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering isatty(STDERR_FILENO) <= 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (log_target == LOG_TARGET_AUTO ||
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_target == LOG_TARGET_JOURNAL) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = log_open_journal();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r >= 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_close_syslog();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_close_console();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack log_target == LOG_TARGET_SYSLOG) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = log_open_syslog();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r >= 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_close_journal();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_close_console();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (log_target == LOG_TARGET_AUTO ||
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_target == LOG_TARGET_KMSG) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = log_open_kmsg();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r >= 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_close_journal();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_close_syslog();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_close_console();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_close_journal();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_close_syslog();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* Get the real /dev/console if we are PID=1, hence reopen */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_close_console();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return log_open_console();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringvoid log_set_target(LogTarget target) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(target >= 0);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(target < _LOG_TARGET_MAX);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_target = target;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringvoid log_close(void) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_close_journal();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_close_syslog();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_close_kmsg();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_close_console();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringvoid log_forget_fds(void) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering console_fd = kmsg_fd = syslog_fd = journal_fd = -1;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringvoid log_set_max_level(int level) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert((level & LOG_PRIMASK) == level);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack log_max_level = level;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack}
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringvoid log_set_facility(int facility) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_facility = facility;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mackstatic int write_to_console(
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack int level,
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack const char*file,
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack int line,
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack const char *func,
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack const char *buffer) {
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack char location[64];
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack struct iovec iovec[5];
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering unsigned n = 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering bool highlight;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (console_fd < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering highlight = LOG_PRI(level) <= LOG_ERR && show_color;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering zero(iovec);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (show_location) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering snprintf(location, sizeof(location), "(%s:%u) ", file, line);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering char_array_0(location);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering IOVEC_SET_STRING(iovec[n++], location);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack if (highlight)
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_RED_ON);
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack IOVEC_SET_STRING(iovec[n++], buffer);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (highlight)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_OFF);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering IOVEC_SET_STRING(iovec[n++], "\n");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (writev(console_fd, iovec, n) < 0)
16ac401407959cbc62312e61c2dd76dbc3a0793bLennart Poettering return -errno;
16ac401407959cbc62312e61c2dd76dbc3a0793bLennart Poettering
ff975efb2e88dcd5221a2f0d76c4c87e85b821a8Lennart Poettering return 1;
16ac401407959cbc62312e61c2dd76dbc3a0793bLennart Poettering}
16ac401407959cbc62312e61c2dd76dbc3a0793bLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int write_to_syslog(
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int level,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char*file,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int line,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *func,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *buffer) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering char header_priority[16], header_time[64], header_pid[16];
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering struct iovec iovec[5];
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering struct msghdr msghdr;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering time_t t;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering struct tm *tm;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (syslog_fd < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering snprintf(header_priority, sizeof(header_priority), "<%i>", level);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering char_array_0(header_priority);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering t = (time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!(tm = localtime(&t)))
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return -EINVAL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return -EINVAL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) getpid());
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering char_array_0(header_pid);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering zero(iovec);
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack IOVEC_SET_STRING(iovec[0], header_priority);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering IOVEC_SET_STRING(iovec[1], header_time);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering IOVEC_SET_STRING(iovec[2], program_invocation_short_name);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering IOVEC_SET_STRING(iovec[3], header_pid);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering IOVEC_SET_STRING(iovec[4], buffer);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* When using syslog via SOCK_STREAM separate the messages by NUL chars */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (syslog_is_stream)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering iovec[4].iov_len++;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering zero(msghdr);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering msghdr.msg_iov = iovec;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering msghdr.msg_iovlen = ELEMENTSOF(iovec);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering for (;;) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering ssize_t n;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (n < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return -errno;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!syslog_is_stream ||
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering (size_t) n >= IOVEC_TOTAL_SIZE(iovec, ELEMENTSOF(iovec)))
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack break;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering IOVEC_INCREMENT(iovec, ELEMENTSOF(iovec), n);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 1;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int write_to_kmsg(
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int level,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char*file,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int line,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *func,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *buffer) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering char header_priority[16], header_pid[16];
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering struct iovec iovec[5];
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (kmsg_fd < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering snprintf(header_priority, sizeof(header_priority), "<%i>", level);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering char_array_0(header_priority);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) getpid());
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering char_array_0(header_pid);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering zero(iovec);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering IOVEC_SET_STRING(iovec[0], header_priority);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering IOVEC_SET_STRING(iovec[1], program_invocation_short_name);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering IOVEC_SET_STRING(iovec[2], header_pid);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering IOVEC_SET_STRING(iovec[3], buffer);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering IOVEC_SET_STRING(iovec[4], "\n");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (writev(kmsg_fd, iovec, ELEMENTSOF(iovec)) < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return -errno;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 1;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int write_to_journal(
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int level,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char*file,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int line,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *func,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *buffer) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering char header[LINE_MAX];
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering struct iovec iovec[3];
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering struct msghdr mh;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (journal_fd < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering snprintf(header, sizeof(header),
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering "PRIORITY=%i\n"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering "SYSLOG_FACILITY=%i\n"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering "CODE_FILE=%s\n"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering "CODE_LINE=%i\n"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering "CODE_FUNCTION=%s\n"
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering "MESSAGE=",
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering LOG_PRI(level),
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering LOG_FAC(level),
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering file,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering line,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering func);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering char_array_0(header);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering zero(iovec);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering IOVEC_SET_STRING(iovec[0], header);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering IOVEC_SET_STRING(iovec[1], buffer);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering IOVEC_SET_STRING(iovec[2], "\n");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering zero(mh);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering mh.msg_iov = iovec;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering mh.msg_iovlen = ELEMENTSOF(iovec);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return -errno;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 1;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int log_dispatch(
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int level,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char*file,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int line,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *func,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering char *buffer) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r = 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (log_target == LOG_TARGET_NULL)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* Patch in LOG_DAEMON facility if necessary */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if ((level & LOG_FACMASK) == 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering level = log_facility | LOG_PRI(level);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering do {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering char *e;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int k = 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering buffer += strspn(buffer, NEWLINE);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (buffer[0] == 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering break;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if ((e = strpbrk(buffer, NEWLINE)))
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering *(e++) = 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (log_target == LOG_TARGET_AUTO ||
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_target == LOG_TARGET_JOURNAL) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering k = write_to_journal(level, file, line, func, buffer);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (k < 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (k != -EAGAIN)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_close_journal();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_open_kmsg();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering } else if (k > 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r++;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_target == LOG_TARGET_SYSLOG) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering k = write_to_syslog(level, file, line, func, buffer);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (k < 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (k != -EAGAIN)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_close_syslog();
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering log_open_kmsg();
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering } else if (k > 0)
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering r++;
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering }
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering if (k <= 0 &&
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering (log_target == LOG_TARGET_AUTO ||
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_target == LOG_TARGET_KMSG)) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering k = write_to_kmsg(level, file, line, func, buffer);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (k < 0) {
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack log_close_kmsg();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_open_console();
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering } else if (k > 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r++;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (k <= 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering k = write_to_console(level, file, line, func, buffer);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (k < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return k;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
700ff4d97311902a440109a2c081731ab6ae8a20Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering buffer = e;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering } while (buffer);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
54d76c92868838e17d6aad0a3bb0cc7a5b11e35fDaniel Mack}
54d76c92868838e17d6aad0a3bb0cc7a5b11e35fDaniel Mack
54d76c92868838e17d6aad0a3bb0cc7a5b11e35fDaniel Mackint log_dump_internal(
54d76c92868838e17d6aad0a3bb0cc7a5b11e35fDaniel Mack int level,
54d76c92868838e17d6aad0a3bb0cc7a5b11e35fDaniel Mack const char*file,
54d76c92868838e17d6aad0a3bb0cc7a5b11e35fDaniel Mack int line,
54d76c92868838e17d6aad0a3bb0cc7a5b11e35fDaniel Mack const char *func,
54d76c92868838e17d6aad0a3bb0cc7a5b11e35fDaniel Mack char *buffer) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int saved_errno, r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* This modifies the buffer... */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (_likely_(LOG_PRI(level) > log_max_level))
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering saved_errno = errno;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = log_dispatch(level, file, line, func, buffer);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering errno = saved_errno;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringint log_metav(
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int level,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char*file,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int line,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *func,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *format,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering va_list ap) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering char buffer[LINE_MAX];
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int saved_errno, r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (_likely_(LOG_PRI(level) > log_max_level))
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering saved_errno = errno;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering vsnprintf(buffer, sizeof(buffer), format, ap);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering char_array_0(buffer);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = log_dispatch(level, file, line, func, buffer);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering errno = saved_errno;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringint log_meta(
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int level,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char*file,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int line,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *func,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *format, ...) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
va_list ap;
va_start(ap, format);
r = log_metav(level, file, line, func, format, ap);
va_end(ap);
return r;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
_noreturn_ static void log_assert(const char *text, const char *file, int line, const char *func, const char *format) {
static char buffer[LINE_MAX];
snprintf(buffer, sizeof(buffer), format, text, file, line, func);
char_array_0(buffer);
log_abort_msg = buffer;
log_dispatch(LOG_CRIT, file, line, func, buffer);
abort();
}
#pragma GCC diagnostic pop
_noreturn_ void log_assert_failed(const char *text, const char *file, int line, const char *func) {
log_assert(text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
}
_noreturn_ void log_assert_failed_unreachable(const char *text, const char *file, int line, const char *func) {
log_assert(text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
}
int log_set_target_from_string(const char *e) {
LogTarget t;
t = log_target_from_string(e);
if (t < 0)
return -EINVAL;
log_set_target(t);
return 0;
}
int log_set_max_level_from_string(const char *e) {
int t;
t = log_level_from_string(e);
if (t < 0)
return t;
log_set_max_level(t);
return 0;
}
void log_parse_environment(void) {
const char *e;
if ((e = getenv("SYSTEMD_LOG_TARGET")))
if (log_set_target_from_string(e) < 0)
log_warning("Failed to parse log target %s. Ignoring.", e);
if ((e = getenv("SYSTEMD_LOG_LEVEL")))
if (log_set_max_level_from_string(e) < 0)
log_warning("Failed to parse log level %s. Ignoring.", e);
if ((e = getenv("SYSTEMD_LOG_COLOR")))
if (log_show_color_from_string(e) < 0)
log_warning("Failed to parse bool %s. Ignoring.", e);
if ((e = getenv("SYSTEMD_LOG_LOCATION")))
if (log_show_location_from_string(e) < 0)
log_warning("Failed to parse bool %s. Ignoring.", e);
}
LogTarget log_get_target(void) {
return log_target;
}
int log_get_max_level(void) {
return log_max_level;
}
void log_show_color(bool b) {
show_color = b;
}
void log_show_location(bool b) {
show_location = b;
}
int log_show_color_from_string(const char *e) {
int t;
t = parse_boolean(e);
if (t < 0)
return t;
log_show_color(t);
return 0;
}
int log_show_location_from_string(const char *e) {
int t;
t = parse_boolean(e);
if (t < 0)
return t;
log_show_location(t);
return 0;
}
static const char *const log_target_table[] = {
[LOG_TARGET_CONSOLE] = "console",
[LOG_TARGET_KMSG] = "kmsg",
[LOG_TARGET_JOURNAL] = "journal",
[LOG_TARGET_JOURNAL_OR_KMSG] = "journal-or-kmsg",
[LOG_TARGET_SYSLOG] = "syslog",
[LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg",
[LOG_TARGET_AUTO] = "auto",
[LOG_TARGET_NULL] = "null"
};
DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget);