1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-07-14 16:59:31 +03:00

log: add an "error" parameter to all low-level logging calls and intrdouce log_error_errno() as log calls that take error numbers

This change has two benefits:

- The format string %m will now resolve to the specified error (or to
  errno if the specified error is 0. This allows getting rid of a ton of
  strerror() invocations, a function that is not thread-safe.

- The specified error can be passed to the journal in the ERRNO= field.

Now of course, we just need somebody to convert all cases of this:

        log_error("Something happened: %s", strerror(-r));

into thus:

        log_error_errno(-r, "Something happened: %m");
This commit is contained in:
Lennart Poettering
2014-11-27 19:48:02 +01:00
parent fb6d9b77a7
commit 086891e5c1
21 changed files with 209 additions and 153 deletions

View File

@ -44,7 +44,7 @@ static void systemd_kmod_log(
/* library logging is enabled at debug only */ /* library logging is enabled at debug only */
DISABLE_WARNING_FORMAT_NONLITERAL; DISABLE_WARNING_FORMAT_NONLITERAL;
log_metav(LOG_DEBUG, file, line, fn, format, args); log_metav(LOG_DEBUG, 0, file, line, fn, format, args);
REENABLE_WARNING; REENABLE_WARNING;
} }

View File

@ -112,7 +112,7 @@ _printf_(2, 3) static int log_callback(int type, const char *fmt, ...) {
#endif #endif
va_start(ap, fmt); va_start(ap, fmt);
log_metav(LOG_USER | LOG_INFO, __FILE__, __LINE__, __FUNCTION__, fmt, ap); log_metav(LOG_USER | LOG_INFO, 0, __FILE__, __LINE__, __FUNCTION__, fmt, ap);
va_end(ap); va_end(ap);
return 0; return 0;

View File

@ -596,7 +596,9 @@ UnitActiveState unit_active_state_from_string(const char *s) _pure_;
/* Macros which append UNIT= or USER_UNIT= to the message */ /* Macros which append UNIT= or USER_UNIT= to the message */
#define log_full_unit(level, unit, ...) log_meta_object(level, __FILE__, __LINE__, __func__, getpid() == 1 ? "UNIT=" : "USER_UNIT=", unit, __VA_ARGS__) #define log_full_unit(level, unit, ...) log_meta_object(level, 0, __FILE__, __LINE__, __func__, getpid() == 1 ? "UNIT=" : "USER_UNIT=", unit, __VA_ARGS__)
#define log_full_unit_errno(level, error, unit, ...) log_meta_object(level, error, __FILE__, __LINE__, __func__, getpid() == 1 ? "UNIT=" : "USER_UNIT=", unit, __VA_ARGS__)
#define log_debug_unit(unit, ...) log_full_unit(LOG_DEBUG, unit, __VA_ARGS__) #define log_debug_unit(unit, ...) log_full_unit(LOG_DEBUG, unit, __VA_ARGS__)
#define log_info_unit(unit, ...) log_full_unit(LOG_INFO, unit, __VA_ARGS__) #define log_info_unit(unit, ...) log_full_unit(LOG_INFO, unit, __VA_ARGS__)
#define log_notice_unit(unit, ...) log_full_unit(LOG_NOTICE, unit, __VA_ARGS__) #define log_notice_unit(unit, ...) log_full_unit(LOG_NOTICE, unit, __VA_ARGS__)

View File

@ -41,7 +41,7 @@ void microhttpd_logger(void *arg, const char *fmt, va_list ap) {
f = strappenda("microhttpd: ", fmt); f = strappenda("microhttpd: ", fmt);
DISABLE_WARNING_FORMAT_NONLITERAL; DISABLE_WARNING_FORMAT_NONLITERAL;
log_metav(LOG_INFO, NULL, 0, NULL, f, ap); log_metav(LOG_INFO, 0, NULL, 0, NULL, f, ap);
REENABLE_WARNING; REENABLE_WARNING;
} }
@ -126,11 +126,10 @@ void log_func_gnutls(int level, const char *message) {
if (0 <= level && level < (int) ELEMENTSOF(gnutls_log_map)) { if (0 <= level && level < (int) ELEMENTSOF(gnutls_log_map)) {
if (gnutls_log_map[level].enabled) if (gnutls_log_map[level].enabled)
log_meta(gnutls_log_map[level].level, NULL, 0, NULL, log_meta(gnutls_log_map[level].level, 0, NULL, 0, NULL, "gnutls %d/%s: %s", level, gnutls_log_map[level].names[1], message);
"gnutls %d/%s: %s", level, gnutls_log_map[level].names[1], message);
} else { } else {
log_debug("Received GNUTLS message with unknown level %d.", level); log_debug("Received GNUTLS message with unknown level %d.", level);
log_meta(LOG_DEBUG, NULL, 0, NULL, "gnutls: %s", message); log_meta(LOG_DEBUG, 0, NULL, 0, NULL, "gnutls: %s", message);
} }
} }

View File

@ -71,4 +71,4 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_client*, sd_dhcp_client_unref);
#define DHCP_CLIENT_DONT_DESTROY(client) \ #define DHCP_CLIENT_DONT_DESTROY(client) \
_cleanup_dhcp_client_unref_ _unused_ sd_dhcp_client *_dont_destroy_##client = sd_dhcp_client_ref(client) _cleanup_dhcp_client_unref_ _unused_ sd_dhcp_client *_dont_destroy_##client = sd_dhcp_client_ref(client)
#define log_dhcp_client(client, fmt, ...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__) #define log_dhcp_client(client, fmt, ...) log_meta(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__)

View File

@ -79,7 +79,7 @@ typedef struct DHCPRequest {
DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_server*, sd_dhcp_server_unref); DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_server*, sd_dhcp_server_unref);
#define _cleanup_dhcp_server_unref_ _cleanup_(sd_dhcp_server_unrefp) #define _cleanup_dhcp_server_unref_ _cleanup_(sd_dhcp_server_unrefp)
#define log_dhcp_server(client, fmt, ...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, "DHCP SERVER: " fmt, ##__VA_ARGS__) #define log_dhcp_server(client, fmt, ...) log_meta(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "DHCP SERVER: " fmt, ##__VA_ARGS__)
int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
size_t length); size_t length);

View File

@ -56,7 +56,7 @@ struct DHCP6IA {
typedef struct DHCP6IA DHCP6IA; typedef struct DHCP6IA DHCP6IA;
#define log_dhcp6_client(p, fmt, ...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__) #define log_dhcp6_client(p, fmt, ...) log_meta(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__)
int dhcp_network_icmp6_bind_router_solicitation(int index); int dhcp_network_icmp6_bind_router_solicitation(int index);
int dhcp_network_icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr); int dhcp_network_icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr);

View File

@ -35,4 +35,4 @@ void arp_packet_probe(struct ether_arp *arp, be32_t pa, const struct ether_addr
void arp_packet_announcement(struct ether_arp *arp, be32_t pa, const struct ether_addr *ha); void arp_packet_announcement(struct ether_arp *arp, be32_t pa, const struct ether_addr *ha);
int arp_packet_verify_headers(struct ether_arp *arp); int arp_packet_verify_headers(struct ether_arp *arp);
#define log_ipv4ll(ll, fmt, ...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, "IPv4LL: " fmt, ##__VA_ARGS__) #define log_ipv4ll(ll, fmt, ...) log_meta(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "IPv4LL: " fmt, ##__VA_ARGS__)

View File

@ -54,7 +54,7 @@ struct sd_icmp6_nd {
void *userdata; void *userdata;
}; };
#define log_icmp6_nd(p, fmt, ...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, "ICMPv6 CLIENT: " fmt, ##__VA_ARGS__) #define log_icmp6_nd(p, fmt, ...) log_meta(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "ICMPv6 CLIENT: " fmt, ##__VA_ARGS__)
static void icmp6_nd_notify(sd_icmp6_nd *nd, int event) static void icmp6_nd_notify(sd_icmp6_nd *nd, int event)
{ {

View File

@ -44,7 +44,7 @@ static void systemd_kmod_log(void *data, int priority, const char *file, int lin
const char *fn, const char *format, va_list args) { const char *fn, const char *format, va_list args) {
DISABLE_WARNING_FORMAT_NONLITERAL; DISABLE_WARNING_FORMAT_NONLITERAL;
log_metav(priority, file, line, fn, format, args); log_metav(priority, 0, file, line, fn, format, args);
REENABLE_WARNING; REENABLE_WARNING;
} }

View File

@ -40,8 +40,7 @@ static int ipv4ll_address_lost(Link *link) {
if (r < 0) if (r < 0)
return 0; return 0;
log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u", log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u", ADDRESS_FMT_VAL(addr));
ADDRESS_FMT_VAL(addr));
r = address_new_dynamic(&address); r = address_new_dynamic(&address);
if (r < 0) { if (r < 0) {

View File

@ -132,7 +132,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_unref);
/* Macros which append INTERFACE= to the message */ /* Macros which append INTERFACE= to the message */
#define log_full_link(level, link, fmt, ...) log_meta_object(level, __FILE__, __LINE__, __func__, "INTERFACE=", link->ifname, "%-*s: " fmt, IFNAMSIZ, link->ifname, ##__VA_ARGS__) #define log_full_link(level, link, fmt, ...) log_meta_object(level, 0, __FILE__, __LINE__, __func__, "INTERFACE=", link->ifname, "%-*s: " fmt, IFNAMSIZ, link->ifname, ##__VA_ARGS__)
#define log_debug_link(link, ...) log_full_link(LOG_DEBUG, link, ##__VA_ARGS__) #define log_debug_link(link, ...) log_full_link(LOG_DEBUG, link, ##__VA_ARGS__)
#define log_info_link(link, ...) log_full_link(LOG_INFO, link, ##__VA_ARGS__) #define log_info_link(link, ...) log_full_link(LOG_INFO, link, ##__VA_ARGS__)
#define log_notice_link(link, ...) log_full_link(LOG_NOTICE, link, ##__VA_ARGS__) #define log_notice_link(link, ...) log_full_link(LOG_NOTICE, link, ##__VA_ARGS__)

View File

@ -65,7 +65,6 @@ static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind); DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind);
DEFINE_CONFIG_PARSE_ENUM(config_parse_netdev_kind, netdev_kind, NetDevKind, "Failed to parse netdev kind"); DEFINE_CONFIG_PARSE_ENUM(config_parse_netdev_kind, netdev_kind, NetDevKind, "Failed to parse netdev kind");
static void netdev_cancel_callbacks(NetDev *netdev) { static void netdev_cancel_callbacks(NetDev *netdev) {
_cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL; _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
netdev_join_callback *callback; netdev_join_callback *callback;

View File

@ -192,7 +192,7 @@ const struct ConfigPerfItem* network_netdev_gperf_lookup(const char *key, unsign
/* Macros which append INTERFACE= to the message */ /* Macros which append INTERFACE= to the message */
#define log_full_netdev(level, netdev, fmt, ...) log_meta_object(level, __FILE__, __LINE__, __func__, "INTERFACE=", netdev->ifname, "%-*s: " fmt, IFNAMSIZ, netdev->ifname, ##__VA_ARGS__) #define log_full_netdev(level, netdev, fmt, ...) log_meta_object(level, 0, __FILE__, __LINE__, __func__, "INTERFACE=", netdev->ifname, "%-*s: " fmt, IFNAMSIZ, netdev->ifname, ##__VA_ARGS__)
#define log_debug_netdev(netdev, ...) log_full_netdev(LOG_DEBUG, netdev, ##__VA_ARGS__) #define log_debug_netdev(netdev, ...) log_full_netdev(LOG_DEBUG, netdev, ##__VA_ARGS__)
#define log_info_netdev(netdev, ...) log_full_netdev(LOG_INFO, netdev, ##__VA_ARGS__) #define log_info_netdev(netdev, ...) log_full_netdev(LOG_INFO, netdev, ##__VA_ARGS__)
#define log_notice_netdev(netdev, ...) log_full_netdev(LOG_NOTICE, netdev, ##__VA_ARGS__) #define log_notice_netdev(netdev, ...) log_full_netdev(LOG_NOTICE, netdev, ##__VA_ARGS__)

View File

@ -336,7 +336,7 @@ int address_pool_acquire(AddressPool *p, unsigned prefixlen, union in_addr_union
/* Macros which append INTERFACE= to the message */ /* Macros which append INTERFACE= to the message */
#define log_full_link(level, link, fmt, ...) log_meta_object(level, __FILE__, __LINE__, __func__, "INTERFACE=", link->ifname, "%-*s: " fmt, IFNAMSIZ, link->ifname, ##__VA_ARGS__) #define log_full_link(level, link, fmt, ...) log_meta_object(level, 0, __FILE__, __LINE__, __func__, "INTERFACE=", link->ifname, "%-*s: " fmt, IFNAMSIZ, link->ifname, ##__VA_ARGS__)
#define log_debug_link(link, ...) log_full_link(LOG_DEBUG, link, ##__VA_ARGS__) #define log_debug_link(link, ...) log_full_link(LOG_DEBUG, link, ##__VA_ARGS__)
#define log_info_link(link, ...) log_full_link(LOG_INFO, link, ##__VA_ARGS__) #define log_info_link(link, ...) log_full_link(LOG_INFO, link, ##__VA_ARGS__)
#define log_notice_link(link, ...) log_full_link(LOG_NOTICE, link, ##__VA_ARGS__) #define log_notice_link(link, ...) log_full_link(LOG_NOTICE, link, ##__VA_ARGS__)

View File

@ -38,10 +38,16 @@
#include "exit-status.h" #include "exit-status.h"
#include "sd-messages.h" #include "sd-messages.h"
int log_syntax_internal(const char *unit, int level, int log_syntax_internal(
const char *file, unsigned line, const char *func, const char *unit,
const char *config_file, unsigned config_line, int level,
int error, const char *format, ...) { const char *file,
int line,
const char *func,
const char *config_file,
unsigned config_line,
int error,
const char *format, ...) {
_cleanup_free_ char *msg = NULL; _cleanup_free_ char *msg = NULL;
int r; int r;
@ -55,21 +61,21 @@ int log_syntax_internal(const char *unit, int level,
if (unit) if (unit)
r = log_struct_internal(level, r = log_struct_internal(level,
error > 0 ? error : EINVAL,
file, line, func, file, line, func,
getpid() == 1 ? "UNIT=%s" : "USER_UNIT=%s", unit, getpid() == 1 ? "UNIT=%s" : "USER_UNIT=%s", unit,
MESSAGE_ID(SD_MESSAGE_CONFIG_ERROR), MESSAGE_ID(SD_MESSAGE_CONFIG_ERROR),
"CONFIG_FILE=%s", config_file, "CONFIG_FILE=%s", config_file,
"CONFIG_LINE=%u", config_line, "CONFIG_LINE=%u", config_line,
"ERRNO=%d", error > 0 ? error : EINVAL,
"MESSAGE=[%s:%u] %s", config_file, config_line, msg, "MESSAGE=[%s:%u] %s", config_file, config_line, msg,
NULL); NULL);
else else
r = log_struct_internal(level, r = log_struct_internal(level,
error > 0 ? error : EINVAL,
file, line, func, file, line, func,
MESSAGE_ID(SD_MESSAGE_CONFIG_ERROR), MESSAGE_ID(SD_MESSAGE_CONFIG_ERROR),
"CONFIG_FILE=%s", config_file, "CONFIG_FILE=%s", config_file,
"CONFIG_LINE=%u", config_line, "CONFIG_LINE=%u", config_line,
"ERRNO=%d", error > 0 ? error : EINVAL,
"MESSAGE=[%s:%u] %s", config_file, config_line, msg, "MESSAGE=[%s:%u] %s", config_file, config_line, msg,
NULL); NULL);

View File

@ -119,10 +119,16 @@ int config_parse_mode(const char *unit, const char *filename, unsigned line, con
int config_parse_log_facility(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_log_facility(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_log_level(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_log_level(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int log_syntax_internal(const char *unit, int level, int log_syntax_internal(
const char *file, unsigned line, const char *func, const char *unit,
const char *config_file, unsigned config_line, int level,
int error, const char *format, ...) _printf_(9, 10); const char *file,
int line,
const char *func,
const char *config_file,
unsigned config_line,
int error,
const char *format, ...) _printf_(9, 10);
#define log_syntax(unit, level, config_file, config_line, error, ...) \ #define log_syntax(unit, level, config_file, config_line, error, ...) \
log_syntax_internal(unit, level, \ log_syntax_internal(unit, level, \

View File

@ -122,7 +122,7 @@ static int create_log_socket(int type) {
timeval_store(&tv, 10 * USEC_PER_MSEC); timeval_store(&tv, 10 * USEC_PER_MSEC);
else else
timeval_store(&tv, 10 * USEC_PER_SEC); timeval_store(&tv, 10 * USEC_PER_SEC);
(void)setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); (void) setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
return fd; return fd;
} }
@ -302,10 +302,11 @@ void log_set_facility(int facility) {
static int write_to_console( static int write_to_console(
int level, int level,
int error,
const char*file, const char*file,
int line, int line,
const char *func, const char *func,
const char *object_name, const char *object_field,
const char *object, const char *object,
const char *buffer) { const char *buffer) {
@ -356,13 +357,14 @@ static int write_to_console(
} }
static int write_to_syslog( static int write_to_syslog(
int level, int level,
const char*file, int error,
int line, const char*file,
const char *func, int line,
const char *object_name, const char *func,
const char *object, const char *object_field,
const char *buffer) { const char *object,
const char *buffer) {
char header_priority[16], header_time[64], header_pid[16]; char header_priority[16], header_time[64], header_pid[16];
struct iovec iovec[5] = {}; struct iovec iovec[5] = {};
@ -418,13 +420,14 @@ static int write_to_syslog(
} }
static int write_to_kmsg( static int write_to_kmsg(
int level, int level,
const char*file, int error,
int line, const char*file,
const char *func, int line,
const char *object_name, const char *func,
const char *object, const char *object_field,
const char *buffer) { const char *object,
const char *buffer) {
char header_priority[16], header_pid[16]; char header_priority[16], header_pid[16];
struct iovec iovec[5] = {}; struct iovec iovec[5] = {};
@ -450,45 +453,55 @@ static int write_to_kmsg(
return 1; return 1;
} }
static int log_do_header(char *header, size_t size, static int log_do_header(
int level, char *header,
const char *file, int line, const char *func, size_t size,
const char *object_name, const char *object) { int level,
int error,
const char *file, int line, const char *func,
const char *object_field, const char *object) {
snprintf(header, size, snprintf(header, size,
"PRIORITY=%i\n" "PRIORITY=%i\n"
"SYSLOG_FACILITY=%i\n" "SYSLOG_FACILITY=%i\n"
"%s%.*s%s" "%s%s%s"
"%s%.*i%s" "%s%.*i%s"
"%s%.*s%s" "%s%s%s"
"%s%.*s%s" "%s%.*i%s"
"%s%s%s"
"SYSLOG_IDENTIFIER=%s\n", "SYSLOG_IDENTIFIER=%s\n",
LOG_PRI(level), LOG_PRI(level),
LOG_FAC(level), LOG_FAC(level),
file ? "CODE_FILE=" : "", isempty(file) ? "" : "CODE_FILE=",
file ? LINE_MAX : 0, file, /* %.0s means no output */ isempty(file) ? "" : file,
file ? "\n" : "", isempty(file) ? "" : "\n",
line ? "CODE_LINE=" : "", line ? "CODE_LINE=" : "",
line ? 1 : 0, line, /* %.0d means no output too, special case for 0 */ line ? 1 : 0, line, /* %.0d means no output too, special case for 0 */
line ? "\n" : "", line ? "\n" : "",
func ? "CODE_FUNCTION=" : "", isempty(func) ? "" : "CODE_FUNCTION=",
func ? LINE_MAX : 0, func, isempty(func) ? "" : func,
func ? "\n" : "", isempty(func) ? "" : "\n",
object ? object_name : "", error ? "ERRNO=" : "",
object ? LINE_MAX : 0, object, /* %.0s means no output */ error ? 1 : 0, error,
object ? "\n" : "", error ? "\n" : "",
isempty(object) ? "" : object_field,
isempty(object) ? "" : object,
isempty(object) ? "" : "\n",
program_invocation_short_name); program_invocation_short_name);
header[size - 1] = '\0'; header[size - 1] = '\0';
return 0; return 0;
} }
static int write_to_journal( static int write_to_journal(
int level, int level,
const char*file, int error,
int line, const char*file,
const char *func, int line,
const char *object_name, const char *func,
const char *object, const char *object_field,
const char *buffer) { const char *object,
const char *buffer) {
char header[LINE_MAX]; char header[LINE_MAX];
struct iovec iovec[4] = {}; struct iovec iovec[4] = {};
@ -497,8 +510,7 @@ static int write_to_journal(
if (journal_fd < 0) if (journal_fd < 0)
return 0; return 0;
log_do_header(header, sizeof(header), level, log_do_header(header, sizeof(header), level, error, file, line, func, object_field, object);
file, line, func, object_name, object);
IOVEC_SET_STRING(iovec[0], header); IOVEC_SET_STRING(iovec[0], header);
IOVEC_SET_STRING(iovec[1], "MESSAGE="); IOVEC_SET_STRING(iovec[1], "MESSAGE=");
@ -515,13 +527,14 @@ static int write_to_journal(
} }
static int log_dispatch( static int log_dispatch(
int level, int level,
const char*file, int error,
int line, const char*file,
const char *func, int line,
const char *object_name, const char *func,
const char *object, const char *object_field,
char *buffer) { const char *object,
char *buffer) {
int r = 0; int r = 0;
@ -548,8 +561,7 @@ static int log_dispatch(
log_target == LOG_TARGET_JOURNAL_OR_KMSG || log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
log_target == LOG_TARGET_JOURNAL) { log_target == LOG_TARGET_JOURNAL) {
k = write_to_journal(level, file, line, func, k = write_to_journal(level, error, file, line, func, object_field, object, buffer);
object_name, object, buffer);
if (k < 0) { if (k < 0) {
if (k != -EAGAIN) if (k != -EAGAIN)
log_close_journal(); log_close_journal();
@ -561,8 +573,7 @@ static int log_dispatch(
if (log_target == LOG_TARGET_SYSLOG_OR_KMSG || if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
log_target == LOG_TARGET_SYSLOG) { log_target == LOG_TARGET_SYSLOG) {
k = write_to_syslog(level, file, line, func, k = write_to_syslog(level, error, file, line, func, object_field, object, buffer);
object_name, object, buffer);
if (k < 0) { if (k < 0) {
if (k != -EAGAIN) if (k != -EAGAIN)
log_close_syslog(); log_close_syslog();
@ -578,8 +589,7 @@ static int log_dispatch(
log_target == LOG_TARGET_JOURNAL_OR_KMSG || log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
log_target == LOG_TARGET_KMSG)) { log_target == LOG_TARGET_KMSG)) {
k = write_to_kmsg(level, file, line, func, k = write_to_kmsg(level, error, file, line, func, object_field, object, buffer);
object_name, object, buffer);
if (k < 0) { if (k < 0) {
log_close_kmsg(); log_close_kmsg();
log_open_console(); log_open_console();
@ -588,8 +598,7 @@ static int log_dispatch(
} }
if (k <= 0) { if (k <= 0) {
k = write_to_console(level, file, line, func, k = write_to_console(level, error, file, line, func, object_field, object, buffer);
object_name, object, buffer);
if (k < 0) if (k < 0)
return k; return k;
} }
@ -602,6 +611,7 @@ static int log_dispatch(
int log_dump_internal( int log_dump_internal(
int level, int level,
int error,
const char*file, const char*file,
int line, int line,
const char *func, const char *func,
@ -614,16 +624,17 @@ int log_dump_internal(
if (_likely_(LOG_PRI(level) > log_max_level)) if (_likely_(LOG_PRI(level) > log_max_level))
return 0; return 0;
return log_dispatch(level, file, line, func, NULL, NULL, buffer); return log_dispatch(level, error, file, line, func, NULL, NULL, buffer);
} }
int log_metav( int log_metav(
int level, int level,
const char*file, int error,
int line, const char*file,
const char *func, int line,
const char *format, const char *func,
va_list ap) { const char *format,
va_list ap) {
PROTECT_ERRNO; PROTECT_ERRNO;
char buffer[LINE_MAX]; char buffer[LINE_MAX];
@ -631,38 +642,44 @@ int log_metav(
if (_likely_(LOG_PRI(level) > log_max_level)) if (_likely_(LOG_PRI(level) > log_max_level))
return 0; return 0;
/* Make sure that %m maps to the specified error */
if (error != 0)
errno = error;
vsnprintf(buffer, sizeof(buffer), format, ap); vsnprintf(buffer, sizeof(buffer), format, ap);
char_array_0(buffer); char_array_0(buffer);
return log_dispatch(level, file, line, func, NULL, NULL, buffer); return log_dispatch(level, error, file, line, func, NULL, NULL, buffer);
} }
int log_meta( int log_meta(
int level, int level,
const char*file, int error,
int line, const char*file,
const char *func, int line,
const char *format, ...) { const char *func,
const char *format, ...) {
int r; int r;
va_list ap; va_list ap;
va_start(ap, format); va_start(ap, format);
r = log_metav(level, file, line, func, format, ap); r = log_metav(level, error, file, line, func, format, ap);
va_end(ap); va_end(ap);
return r; return r;
} }
int log_metav_object( int log_metav_object(
int level, int level,
const char*file, int error,
int line, const char*file,
const char *func, int line,
const char *object_name, const char *func,
const char *object, const char *object_field,
const char *format, const char *object,
va_list ap) { const char *format,
va_list ap) {
PROTECT_ERRNO; PROTECT_ERRNO;
char buffer[LINE_MAX]; char buffer[LINE_MAX];
@ -670,34 +687,44 @@ int log_metav_object(
if (_likely_(LOG_PRI(level) > log_max_level)) if (_likely_(LOG_PRI(level) > log_max_level))
return 0; return 0;
/* Make sure that %m maps to the specified error */
if (error != 0)
errno = error;
vsnprintf(buffer, sizeof(buffer), format, ap); vsnprintf(buffer, sizeof(buffer), format, ap);
char_array_0(buffer); char_array_0(buffer);
return log_dispatch(level, file, line, func, return log_dispatch(level, error, file, line, func, object_field, object, buffer);
object_name, object, buffer);
} }
int log_meta_object( int log_meta_object(
int level, int level,
const char*file, int error,
int line, const char*file,
const char *func, int line,
const char *object_name, const char *func,
const char *object, const char *object_field,
const char *format, ...) { const char *object,
const char *format, ...) {
int r; int r;
va_list ap; va_list ap;
va_start(ap, format); va_start(ap, format);
r = log_metav_object(level, file, line, func, r = log_metav_object(level, error, file, line, func, object_field, object, format, ap);
object_name, object, format, ap);
va_end(ap); va_end(ap);
return r; return r;
} }
static void log_assert(int level, const char *text, const char *file, int line, const char *func, const char *format) { static void log_assert(
int level,
const char *text,
const char *file,
int line,
const char *func,
const char *format) {
static char buffer[LINE_MAX]; static char buffer[LINE_MAX];
if (_likely_(LOG_PRI(level) > log_max_level)) if (_likely_(LOG_PRI(level) > log_max_level))
@ -710,7 +737,7 @@ static void log_assert(int level, const char *text, const char *file, int line,
char_array_0(buffer); char_array_0(buffer);
log_abort_msg = buffer; log_abort_msg = buffer;
log_dispatch(level, file, line, func, NULL, NULL, buffer); log_dispatch(level, 0, file, line, func, NULL, NULL, buffer);
} }
noreturn void log_assert_failed(const char *text, const char *file, int line, const char *func) { noreturn void log_assert_failed(const char *text, const char *file, int line, const char *func) {
@ -729,12 +756,13 @@ void log_assert_failed_return(const char *text, const char *file, int line, cons
} }
int log_oom_internal(const char *file, int line, const char *func) { int log_oom_internal(const char *file, int line, const char *func) {
log_meta(LOG_ERR, file, line, func, "Out of memory."); log_meta(LOG_ERR, ENOMEM, file, line, func, "Out of memory.");
return -ENOMEM; return -ENOMEM;
} }
int log_struct_internal( int log_struct_internal(
int level, int level,
int error,
const char *file, const char *file,
int line, int line,
const char *func, const char *func,
@ -767,8 +795,7 @@ int log_struct_internal(
static const char nl = '\n'; static const char nl = '\n';
/* If the journal is available do structured logging */ /* If the journal is available do structured logging */
log_do_header(header, sizeof(header), level, log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL);
file, line, func, NULL, NULL);
IOVEC_SET_STRING(iovec[n++], header); IOVEC_SET_STRING(iovec[n++], header);
va_start(ap, format); va_start(ap, format);
@ -840,8 +867,7 @@ int log_struct_internal(
va_end(ap); va_end(ap);
if (found) if (found)
r = log_dispatch(level, file, line, func, r = log_dispatch(level, error, file, line, func, NULL, NULL, buf + 8);
NULL, NULL, buf + 8);
else else
r = -EINVAL; r = -EINVAL;
} }

View File

@ -77,44 +77,49 @@ void log_parse_environment(void);
int log_meta( int log_meta(
int level, int level,
int error,
const char*file, const char*file,
int line, int line,
const char *func, const char *func,
const char *format, ...) _printf_(5,6); const char *format, ...) _printf_(6,7);
int log_metav( int log_metav(
int level, int level,
int error,
const char*file, const char*file,
int line, int line,
const char *func, const char *func,
const char *format, const char *format,
va_list ap) _printf_(5,0); va_list ap) _printf_(6,0);
int log_meta_object( int log_meta_object(
int level, int level,
int error,
const char*file, const char*file,
int line, int line,
const char *func, const char *func,
const char *object_name, const char *object_name,
const char *object, const char *object,
const char *format, ...) _printf_(7,8); const char *format, ...) _printf_(8,9);
int log_metav_object( int log_metav_object(
int level, int level,
int error,
const char*file, const char*file,
int line, int line,
const char *func, const char *func,
const char *object_name, const char *object_name,
const char *object, const char *object,
const char *format, const char *format,
va_list ap) _printf_(7,0); va_list ap) _printf_(8,0);
int log_struct_internal( int log_struct_internal(
int level, int level,
int error,
const char *file, const char *file,
int line, int line,
const char *func, const char *func,
const char *format, ...) _printf_(5,0) _sentinel_; const char *format, ...) _printf_(6,0) _sentinel_;
int log_oom_internal( int log_oom_internal(
const char *file, const char *file,
@ -124,11 +129,13 @@ int log_oom_internal(
/* This modifies the buffer passed! */ /* This modifies the buffer passed! */
int log_dump_internal( int log_dump_internal(
int level, int level,
int error,
const char*file, const char*file,
int line, int line,
const char *func, const char *func,
char *buffer); char *buffer);
/* Logging for various assertions */
noreturn void log_assert_failed( noreturn void log_assert_failed(
const char *text, const char *text,
const char *file, const char *file,
@ -147,12 +154,16 @@ void log_assert_failed_return(
int line, int line,
const char *func); const char *func);
#define log_full(level, ...) \ /* Logging with level */
do { \ #define log_full_errno(level, error, ...) \
if (log_get_max_level() >= (level)) \ do { \
log_meta((level), __FILE__, __LINE__, __func__, __VA_ARGS__); \ if (log_get_max_level() >= (level)) \
} while (0) log_meta((level), error, __FILE__, __LINE__, __func__, __VA_ARGS__); \
} while (false)
#define log_full(level, ...) log_full_errno(level, 0, __VA_ARGS__)
/* Normal logging */
#define log_debug(...) log_full(LOG_DEBUG, __VA_ARGS__) #define log_debug(...) log_full(LOG_DEBUG, __VA_ARGS__)
#define log_info(...) log_full(LOG_INFO, __VA_ARGS__) #define log_info(...) log_full(LOG_INFO, __VA_ARGS__)
#define log_notice(...) log_full(LOG_NOTICE, __VA_ARGS__) #define log_notice(...) log_full(LOG_NOTICE, __VA_ARGS__)
@ -160,18 +171,28 @@ do { \
#define log_error(...) log_full(LOG_ERR, __VA_ARGS__) #define log_error(...) log_full(LOG_ERR, __VA_ARGS__)
#define log_emergency(...) log_full(getpid() == 1 ? LOG_EMERG : 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, __VA_ARGS__)
#ifdef LOG_TRACE #ifdef LOG_TRACE
# define log_trace(...) log_debug(__VA_ARGS__) # define log_trace(...) log_debug(__VA_ARGS__)
#else #else
# define log_trace(...) do {} while(0) # define log_trace(...) do {} while(0)
#endif #endif
#define log_struct(level, ...) log_struct_internal(level, __FILE__, __LINE__, __func__, __VA_ARGS__) /* Structured logging */
#define log_struct(level, ...) log_struct_internal(level, 0, __FILE__, __LINE__, __func__, __VA_ARGS__)
#define log_oom() log_oom_internal(__FILE__, __LINE__, __func__) #define log_struct_errno(level, error, ...) log_struct_internal(level, error, __FILE__, __LINE__, __func__, __VA_ARGS__)
/* This modifies the buffer passed! */ /* This modifies the buffer passed! */
#define log_dump(level, buffer) log_dump_internal(level, __FILE__, __LINE__, __func__, buffer) #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_; bool log_on_console(void) _pure_;

View File

@ -32,7 +32,7 @@ int main(int argc, char* argv[]) {
r = hostname_setup(); r = hostname_setup();
if (r < 0) if (r < 0)
fprintf(stderr, "hostname: %s\n", strerror(-r)); log_error_errno(-r, "hostname: %m");
return 0; return 0;
} }

View File

@ -31,7 +31,7 @@
#include "udev.h" #include "udev.h"
static struct kmod_ctx *ctx; static struct kmod_ctx *ctx = NULL;
static int load_module(struct udev *udev, const char *alias) { static int load_module(struct udev *udev, const char *alias) {
struct kmod_list *list = NULL; struct kmod_list *list = NULL;
@ -43,18 +43,18 @@ static int load_module(struct udev *udev, const char *alias) {
return err; return err;
if (list == NULL) if (list == NULL)
log_debug("no module matches '%s'", alias); log_debug("No module matches '%s'", alias);
kmod_list_foreach(l, list) { kmod_list_foreach(l, list) {
struct kmod_module *mod = kmod_module_get_module(l); struct kmod_module *mod = kmod_module_get_module(l);
err = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL); err = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL);
if (err == KMOD_PROBE_APPLY_BLACKLIST) if (err == KMOD_PROBE_APPLY_BLACKLIST)
log_debug("module '%s' is blacklisted", kmod_module_get_name(mod)); log_debug("Module '%s' is blacklisted", kmod_module_get_name(mod));
else if (err == 0) else if (err == 0)
log_debug("inserted '%s'", kmod_module_get_name(mod)); log_debug("Inserted '%s'", kmod_module_get_name(mod));
else else
log_debug("failed to insert '%s'", kmod_module_get_name(mod)); log_debug("Failed to insert '%s'", kmod_module_get_name(mod));
kmod_module_unref(mod); kmod_module_unref(mod);
} }
@ -63,10 +63,8 @@ static int load_module(struct udev *udev, const char *alias) {
return err; return err;
} }
_printf_(6,0) _printf_(6,0) static void udev_kmod_log(void *data, int priority, const char *file, int line, const char *fn, const char *format, va_list args) {
static void udev_kmod_log(void *data, int priority, const char *file, int line, log_metav(priority, 0, file, line, fn, format, args);
const char *fn, const char *format, va_list args) {
log_metav(priority, file, line, fn, format, args);
} }
static int builtin_kmod(struct udev_device *dev, int argc, char *argv[], bool test) { static int builtin_kmod(struct udev_device *dev, int argc, char *argv[], bool test) {
@ -82,7 +80,7 @@ static int builtin_kmod(struct udev_device *dev, int argc, char *argv[], bool te
} }
for (i = 2; argv[i]; i++) { for (i = 2; argv[i]; i++) {
log_debug("execute '%s' '%s'", argv[1], argv[i]); log_debug("Execute '%s' '%s'", argv[1], argv[i]);
load_module(udev, argv[i]); load_module(udev, argv[i]);
} }
@ -98,7 +96,7 @@ static int builtin_kmod_init(struct udev *udev) {
if (!ctx) if (!ctx)
return -ENOMEM; return -ENOMEM;
log_debug("load module index"); log_debug("Load module index");
kmod_set_log_fn(ctx, udev_kmod_log, udev); kmod_set_log_fn(ctx, udev_kmod_log, udev);
kmod_load_resources(ctx); kmod_load_resources(ctx);
return 0; return 0;
@ -106,13 +104,13 @@ static int builtin_kmod_init(struct udev *udev) {
/* called on udev shutdown and reload request */ /* called on udev shutdown and reload request */
static void builtin_kmod_exit(struct udev *udev) { static void builtin_kmod_exit(struct udev *udev) {
log_debug("unload module index"); log_debug("Unload module index");
ctx = kmod_unref(ctx); ctx = kmod_unref(ctx);
} }
/* called every couple of seconds during event activity; 'true' if config has changed */ /* called every couple of seconds during event activity; 'true' if config has changed */
static bool builtin_kmod_validate(struct udev *udev) { static bool builtin_kmod_validate(struct udev *udev) {
log_debug("validate module index"); log_debug("Validate module index");
if (!ctx) if (!ctx)
return false; return false;
return (kmod_validate_resources(ctx) != KMOD_RESOURCES_OK); return (kmod_validate_resources(ctx) != KMOD_RESOURCES_OK);