f2341e0a87
This changes log_unit_info() (and friends) to take a real Unit* object insted of just a unit name as parameter. The call will now prefix all logged messages with the unit name, thus allowing the unit name to be dropped from the various passed romat strings, simplifying invocations drastically, and unifying log output across messages. Also, UNIT= vs. USER_UNIT= is now derived from the Manager object attached to the Unit object, instead of getpid(). This has the benefit of correcting the field for --test runs. Also contains a couple of other logging improvements: - Drops a couple of strerror() invocations in favour of using %m. - Not only .mount units now warn if a symlinks exist for the mount point already, .automount units do that too, now. - A few invocations of log_struct() that didn't actually pass any additional structured data have been replaced by simpler invocations of log_unit_info() and friends. - For structured data a new LOG_UNIT_MESSAGE() macro has been added, that works like LOG_MESSAGE() but prefixes the message with the unit name. Similar, there's now LOG_LINK_MESSAGE() and LOG_NETDEV_MESSAGE(). - For structured data new LOG_UNIT_ID(), LOG_LINK_INTERFACE(), LOG_NETDEV_INTERFACE() macros have been added that generate the necessary per object fields. The old log_unit_struct() call has been removed in favour of these new macros used in raw log_struct() invocations. In addition to removing one more function call this allows generated structured log messages that contain two object fields, as necessary for example for network interfaces that are joined into another network interface, and whose messages shall be indexed by both. - The LOG_ERRNO() macro has been removed, in favour of log_struct_errno(). The latter has the benefit of ensuring that %m in format strings is properly resolved to the specified error number. - A number of logging messages have been converted to use log_unit_info() instead of log_info() - The client code in sysv-generator no longer #includes core code from src/core/. - log_unit_full_errno() has been removed, log_unit_full() instead takes an errno now, too. - log_unit_info(), log_link_info(), log_netdev_info() and friends, now avoid double evaluation of their parameters
230 lines
7.8 KiB
C
230 lines
7.8 KiB
C
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
|
|
|
#pragma once
|
|
|
|
/***
|
|
This file is part of systemd.
|
|
|
|
Copyright 2010 Lennart Poettering
|
|
|
|
systemd is free software; you can redistribute it and/or modify it
|
|
under the terms of the GNU Lesser General Public License as published by
|
|
the Free Software Foundation; either version 2.1 of the License, or
|
|
(at your option) any later version.
|
|
|
|
systemd is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
|
***/
|
|
|
|
#include <stdbool.h>
|
|
#include <stdarg.h>
|
|
#include <stdlib.h>
|
|
#include <syslog.h>
|
|
#include <sys/signalfd.h>
|
|
#include <errno.h>
|
|
|
|
#include "sd-id128.h"
|
|
#include "macro.h"
|
|
|
|
typedef enum LogTarget{
|
|
LOG_TARGET_CONSOLE,
|
|
LOG_TARGET_CONSOLE_PREFIXED,
|
|
LOG_TARGET_KMSG,
|
|
LOG_TARGET_JOURNAL,
|
|
LOG_TARGET_JOURNAL_OR_KMSG,
|
|
LOG_TARGET_SYSLOG,
|
|
LOG_TARGET_SYSLOG_OR_KMSG,
|
|
LOG_TARGET_AUTO, /* console if stderr is tty, JOURNAL_OR_KMSG otherwise */
|
|
LOG_TARGET_SAFE, /* console if stderr is tty, KMSG otherwise */
|
|
LOG_TARGET_NULL,
|
|
_LOG_TARGET_MAX,
|
|
_LOG_TARGET_INVALID = -1
|
|
} LogTarget;
|
|
|
|
void log_set_target(LogTarget target);
|
|
void log_set_max_level(int level);
|
|
void log_set_facility(int facility);
|
|
|
|
int log_set_target_from_string(const char *e);
|
|
int log_set_max_level_from_string(const char *e);
|
|
|
|
void log_show_color(bool b);
|
|
bool log_get_show_color(void) _pure_;
|
|
void log_show_location(bool b);
|
|
bool log_get_show_location(void) _pure_;
|
|
|
|
int log_show_color_from_string(const char *e);
|
|
int log_show_location_from_string(const char *e);
|
|
|
|
LogTarget log_get_target(void) _pure_;
|
|
int log_get_max_level(void) _pure_;
|
|
|
|
int log_open(void);
|
|
void log_close(void);
|
|
void log_forget_fds(void);
|
|
|
|
void log_close_syslog(void);
|
|
void log_close_journal(void);
|
|
void log_close_kmsg(void);
|
|
void log_close_console(void);
|
|
|
|
void log_parse_environment(void);
|
|
|
|
int log_internal(
|
|
int level,
|
|
int error,
|
|
const char *file,
|
|
int line,
|
|
const char *func,
|
|
const char *format, ...) _printf_(6,7);
|
|
|
|
int log_internalv(
|
|
int level,
|
|
int error,
|
|
const char *file,
|
|
int line,
|
|
const char *func,
|
|
const char *format,
|
|
va_list ap) _printf_(6,0);
|
|
|
|
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, ...) _printf_(8,9);
|
|
|
|
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,
|
|
va_list ap) _printf_(8,0);
|
|
|
|
int log_struct_internal(
|
|
int level,
|
|
int error,
|
|
const char *file,
|
|
int line,
|
|
const char *func,
|
|
const char *format, ...) _printf_(6,0) _sentinel_;
|
|
|
|
int log_oom_internal(
|
|
const char *file,
|
|
int line,
|
|
const char *func);
|
|
|
|
/* This modifies the buffer passed! */
|
|
int log_dump_internal(
|
|
int level,
|
|
int error,
|
|
const char *file,
|
|
int line,
|
|
const char *func,
|
|
char *buffer);
|
|
|
|
/* Logging for various assertions */
|
|
noreturn void log_assert_failed(
|
|
const char *text,
|
|
const char *file,
|
|
int line,
|
|
const char *func);
|
|
|
|
noreturn void log_assert_failed_unreachable(
|
|
const char *text,
|
|
const char *file,
|
|
int line,
|
|
const char *func);
|
|
|
|
void log_assert_failed_return(
|
|
const char *text,
|
|
const char *file,
|
|
int line,
|
|
const char *func);
|
|
|
|
/* Logging with level */
|
|
#define log_full_errno(level, error, ...) \
|
|
({ \
|
|
int _level = (level), _e = (error); \
|
|
(log_get_max_level() >= LOG_PRI(_level)) \
|
|
? log_internal(_level, _e, __FILE__, __LINE__, __func__, __VA_ARGS__) \
|
|
: -abs(_e); \
|
|
})
|
|
|
|
#define log_full(level, ...) log_full_errno(level, 0, __VA_ARGS__)
|
|
|
|
/* Normal logging */
|
|
#define log_debug(...) log_full(LOG_DEBUG, __VA_ARGS__)
|
|
#define log_info(...) log_full(LOG_INFO, __VA_ARGS__)
|
|
#define log_notice(...) log_full(LOG_NOTICE, __VA_ARGS__)
|
|
#define log_warning(...) log_full(LOG_WARNING, __VA_ARGS__)
|
|
#define log_error(...) log_full(LOG_ERR, __VA_ARGS__)
|
|
#define log_emergency(...) log_full(getpid() == 1 ? LOG_EMERG : LOG_ERR, __VA_ARGS__)
|
|
|
|
/* Logging triggered by an errno-like error */
|
|
#define log_debug_errno(error, ...) log_full_errno(LOG_DEBUG, error, __VA_ARGS__)
|
|
#define log_info_errno(error, ...) log_full_errno(LOG_INFO, error, __VA_ARGS__)
|
|
#define log_notice_errno(error, ...) log_full_errno(LOG_NOTICE, error, __VA_ARGS__)
|
|
#define log_warning_errno(error, ...) log_full_errno(LOG_WARNING, error, __VA_ARGS__)
|
|
#define log_error_errno(error, ...) log_full_errno(LOG_ERR, error, __VA_ARGS__)
|
|
#define log_emergency_errno(error, ...) log_full_errno(getpid() == 1 ? LOG_EMERG : LOG_ERR, error, __VA_ARGS__)
|
|
|
|
#ifdef LOG_TRACE
|
|
# define log_trace(...) log_debug(__VA_ARGS__)
|
|
#else
|
|
# define log_trace(...) do {} while(0)
|
|
#endif
|
|
|
|
/* Structured logging */
|
|
#define log_struct(level, ...) log_struct_internal(level, 0, __FILE__, __LINE__, __func__, __VA_ARGS__)
|
|
#define log_struct_errno(level, error, ...) log_struct_internal(level, error, __FILE__, __LINE__, __func__, __VA_ARGS__)
|
|
|
|
/* This modifies the buffer passed! */
|
|
#define log_dump(level, buffer) log_dump_internal(level, 0, __FILE__, __LINE__, __func__, buffer)
|
|
|
|
#define log_oom() log_oom_internal(__FILE__, __LINE__, __func__)
|
|
|
|
bool log_on_console(void) _pure_;
|
|
|
|
const char *log_target_to_string(LogTarget target) _const_;
|
|
LogTarget log_target_from_string(const char *s) _pure_;
|
|
|
|
/* Helpers to prepare various fields for structured logging */
|
|
#define LOG_MESSAGE(fmt, ...) "MESSAGE=" fmt, ##__VA_ARGS__
|
|
#define LOG_MESSAGE_ID(x) "MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(x)
|
|
|
|
void log_received_signal(int level, const struct signalfd_siginfo *si);
|
|
|
|
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, ...) _printf_(9, 10);
|
|
|
|
#define log_syntax(unit, level, config_file, config_line, error, ...) \
|
|
({ \
|
|
int _level = (level), _e = (error); \
|
|
(log_get_max_level() >= LOG_PRI(_level)) \
|
|
? log_syntax_internal(unit, _level, config_file, config_line, _e, __FILE__, __LINE__, __func__, __VA_ARGS__) \
|
|
: -abs(_e); \
|
|
})
|