From ff524019efda6d504dbdddbe5ba6aa3cffb2a7b4 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 22 Feb 2017 22:57:34 -0500 Subject: [PATCH] basic/log: split max log level into multiple "realms" The single log level is split into an array of log levels. Which index in the array is used can be determined for each compilation unit separately by setting a macro before including log.h. All compilation units use the same index (LOG_REALM_SYSTEMD), so there should be no functional change. v2: - the "realm" is squished into the level (upper bits that are not used by priority or facility), and unsquished later in functions in log.c. v3: - rename REALM_PLUS_LEVEL to LOG_REALM_PLUS_LEVEL and REALM to LOG_REALM_REMOVE_LEVEL. --- src/basic/log.c | 94 ++++++++++++++++++++++++++++++++++------------------- src/basic/log.h | 83 ++++++++++++++++++++++++++++++++++++---------- src/test/test-log.c | 9 +++++ 3 files changed, 134 insertions(+), 52 deletions(-) diff --git a/src/basic/log.c b/src/basic/log.c index 0d0ced0..62c9f1a 100644 --- a/src/basic/log.c +++ b/src/basic/log.c @@ -58,7 +58,8 @@ #define SNDBUF_SIZE (8*1024*1024) static LogTarget log_target = LOG_TARGET_CONSOLE; -static int log_max_level = LOG_INFO; +static int log_max_level[] = {LOG_INFO, LOG_INFO}; +assert_cc(ELEMENTSOF(log_max_level) == _LOG_REALM_MAX); static int log_facility = LOG_DAEMON; static int console_fd = STDERR_FILENO; @@ -315,10 +316,11 @@ void log_forget_fds(void) { console_fd = kmsg_fd = syslog_fd = journal_fd = -1; } -void log_set_max_level(int level) { +void log_set_max_level_realm(LogRealm realm, int level) { assert((level & LOG_PRIMASK) == level); + assert(realm < ELEMENTSOF(log_max_level)); - log_max_level = level; + log_max_level[realm] = level; } void log_set_facility(int facility) { @@ -636,13 +638,14 @@ int log_dispatch_internal( } int log_dump_internal( - int level, - int error, - const char *file, - int line, - const char *func, - char *buffer) { + int level, + int error, + const char *file, + int line, + const char *func, + char *buffer) { + LogRealm realm = LOG_REALM_REMOVE_LEVEL(level); PROTECT_ERRNO; /* This modifies the buffer... */ @@ -650,13 +653,13 @@ int log_dump_internal( if (error < 0) error = -error; - if (_likely_(LOG_PRI(level) > log_max_level)) + if (_likely_(LOG_PRI(level) > log_max_level[realm])) return -error; return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer); } -int log_internalv( +int log_internalv_realm( int level, int error, const char *file, @@ -665,13 +668,14 @@ int log_internalv( const char *format, va_list ap) { - PROTECT_ERRNO; + LogRealm realm = LOG_REALM_REMOVE_LEVEL(level); char buffer[LINE_MAX]; + PROTECT_ERRNO; if (error < 0) error = -error; - if (_likely_(LOG_PRI(level) > log_max_level)) + if (_likely_(LOG_PRI(level) > log_max_level[realm])) return -error; /* Make sure that %m maps to the specified error */ @@ -683,7 +687,7 @@ int log_internalv( return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer); } -int log_internal( +int log_internal_realm( int level, int error, const char *file, @@ -695,7 +699,7 @@ int log_internal( int r; va_start(ap, format); - r = log_internalv(level, error, file, line, func, format, ap); + r = log_internalv_realm(level, error, file, line, func, format, ap); va_end(ap); return r; @@ -721,7 +725,7 @@ int log_object_internalv( if (error < 0) error = -error; - if (_likely_(LOG_PRI(level) > log_max_level)) + if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD])) return -error; /* Make sure that %m maps to the specified error */ @@ -779,8 +783,9 @@ static void log_assert( const char *format) { static char buffer[LINE_MAX]; + LogRealm realm = LOG_REALM_REMOVE_LEVEL(level); - if (_likely_(LOG_PRI(level) > log_max_level)) + if (_likely_(LOG_PRI(level) > log_max_level[realm])) return; DISABLE_WARNING_FORMAT_NONLITERAL; @@ -792,23 +797,42 @@ static void log_assert( log_dispatch_internal(level, 0, file, line, func, NULL, NULL, NULL, NULL, buffer); } -noreturn void log_assert_failed(const char *text, const char *file, int line, const char *func) { - log_assert(LOG_CRIT, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting."); +noreturn void log_assert_failed_realm( + LogRealm realm, + const char *text, + const char *file, + int line, + const char *func) { + log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_CRIT), text, file, line, func, + "Assertion '%s' failed at %s:%u, function %s(). Aborting."); abort(); } -noreturn void log_assert_failed_unreachable(const char *text, const char *file, int line, const char *func) { - log_assert(LOG_CRIT, text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting."); +noreturn void log_assert_failed_unreachable_realm( + LogRealm realm, + const char *text, + const char *file, + int line, + const char *func) { + log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_CRIT), text, file, line, func, + "Code should not be reached '%s' at %s:%u, function %s(). Aborting."); abort(); } -void log_assert_failed_return(const char *text, const char *file, int line, const char *func) { +void log_assert_failed_return_realm( + LogRealm realm, + const char *text, + const char *file, + int line, + const char *func) { PROTECT_ERRNO; - log_assert(LOG_DEBUG, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Ignoring."); + log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_DEBUG), text, file, line, func, + "Assertion '%s' failed at %s:%u, function %s(). Ignoring."); } -int log_oom_internal(const char *file, int line, const char *func) { - log_internal(LOG_ERR, ENOMEM, file, line, func, "Out of memory."); +int log_oom_internal(LogRealm realm, const char *file, int line, const char *func) { + log_internal_realm(LOG_REALM_PLUS_LEVEL(realm, LOG_ERR), + ENOMEM, file, line, func, "Out of memory."); return -ENOMEM; } @@ -868,13 +892,14 @@ int log_struct_internal( char buf[LINE_MAX]; bool found = false; + LogRealm realm = LOG_REALM_REMOVE_LEVEL(level); PROTECT_ERRNO; va_list ap; if (error < 0) error = -error; - if (_likely_(LOG_PRI(level) > log_max_level)) + if (_likely_(LOG_PRI(level) > log_max_level[realm])) return -error; if (log_target == LOG_TARGET_NULL) @@ -958,14 +983,14 @@ int log_set_target_from_string(const char *e) { return 0; } -int log_set_max_level_from_string(const char *e) { +int log_set_max_level_from_string_realm(LogRealm realm, const char *e) { int t; t = log_level_from_string(e); if (t < 0) return -EINVAL; - log_set_max_level(t); + log_set_max_level_realm(realm, t); return 0; } @@ -1013,7 +1038,7 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat return 0; } -void log_parse_environment(void) { +void log_parse_environment_realm(LogRealm realm) { const char *e; if (get_ctty_devnr(0, NULL) < 0) @@ -1026,7 +1051,7 @@ void log_parse_environment(void) { log_warning("Failed to parse log target '%s'. Ignoring.", e); e = secure_getenv("SYSTEMD_LOG_LEVEL"); - if (e && log_set_max_level_from_string(e) < 0) + if (e && log_set_max_level_from_string_realm(realm, e) < 0) log_warning("Failed to parse log level '%s'. Ignoring.", e); e = secure_getenv("SYSTEMD_LOG_COLOR"); @@ -1042,8 +1067,8 @@ LogTarget log_get_target(void) { return log_target; } -int log_get_max_level(void) { - return log_max_level; +int log_get_max_level_realm(LogRealm realm) { + return log_max_level[realm]; } void log_show_color(bool b) { @@ -1147,7 +1172,7 @@ int log_syntax_internal( if (error < 0) error = -error; - if (_likely_(LOG_PRI(level) > log_max_level)) + if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD])) return -error; if (log_target == LOG_TARGET_NULL) @@ -1164,7 +1189,8 @@ int log_syntax_internal( unit_fmt = getpid() == 1 ? "UNIT=%s" : "USER_UNIT=%s"; return log_struct_internal( - level, error, + LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level), + error, file, line, func, "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR, "CONFIG_FILE=%s", config_file, diff --git a/src/basic/log.h b/src/basic/log.h index b3e4060..57463fb 100644 --- a/src/basic/log.h +++ b/src/basic/log.h @@ -31,6 +31,16 @@ #include "macro.h" +typedef enum LogRealm { + LOG_REALM_SYSTEMD, + LOG_REALM_UDEV, + _LOG_REALM_MAX, +} LogRealm; + +#ifndef LOG_REALM +# define LOG_REALM LOG_REALM_SYSTEMD +#endif + typedef enum LogTarget{ LOG_TARGET_CONSOLE, LOG_TARGET_CONSOLE_PREFIXED, @@ -44,14 +54,24 @@ typedef enum LogTarget{ LOG_TARGET_NULL, _LOG_TARGET_MAX, _LOG_TARGET_INVALID = -1 -} LogTarget; +} LogTarget; + +#define LOG_REALM_PLUS_LEVEL(realm, level) \ + ((realm) << 10 | (level)) +#define LOG_REALM_REMOVE_LEVEL(realm_level) \ + ((realm_level >> 10)) void log_set_target(LogTarget target); -void log_set_max_level(int level); +void log_set_max_level_realm(LogRealm realm, int level); +#define log_set_max_level(level) \ + log_set_max_level_realm(LOG_REALM, (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); +int log_set_max_level_from_string_realm(LogRealm realm, const char *e); +#define log_set_max_level_from_string(e) \ + log_set_max_level_from_string_realm(LOG_REALM, (e)) void log_show_color(bool b); bool log_get_show_color(void) _pure_; @@ -62,7 +82,9 @@ 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_get_max_level_realm(LogRealm realm) _pure_; +#define log_get_max_level() \ + log_get_max_level_realm(LOG_REALM) int log_open(void); void log_close(void); @@ -73,7 +95,9 @@ void log_close_journal(void); void log_close_kmsg(void); void log_close_console(void); -void log_parse_environment(void); +void log_parse_environment_realm(LogRealm realm); +#define log_parse_environment() \ + log_parse_environment_realm(LOG_REALM) int log_dispatch_internal( int level, @@ -87,15 +111,17 @@ int log_dispatch_internal( const char *extra_field, char *buffer); -int log_internal( +int log_internal_realm( int level, int error, const char *file, int line, const char *func, const char *format, ...) _printf_(6,7); +#define log_internal(level, ...) \ + log_internal_realm(LOG_REALM_PLUS_LEVEL(LOG_REALM, (level)), __VA_ARGS__) -int log_internalv( +int log_internalv_realm( int level, int error, const char *file, @@ -103,7 +129,10 @@ int log_internalv( const char *func, const char *format, va_list ap) _printf_(6,0); +#define log_internalv(level, ...) \ + log_internalv_realm(LOG_REALM_PLUS_LEVEL(LOG_REALM, (level)), __VA_ARGS__) +/* Realm is fixed to LOG_REALM_SYSTEMD for those */ int log_object_internal( int level, int error, @@ -138,6 +167,7 @@ int log_struct_internal( const char *format, ...) _printf_(6,0) _sentinel_; int log_oom_internal( + LogRealm realm, const char *file, int line, const char *func); @@ -161,37 +191,50 @@ int log_dump_internal( char *buffer); /* Logging for various assertions */ -noreturn void log_assert_failed( +noreturn void log_assert_failed_realm( + LogRealm realm, const char *text, const char *file, int line, const char *func); +#define log_assert_failed(text, ...) \ + log_assert_failed_realm(LOG_REALM, (text), __VA_ARGS__) -noreturn void log_assert_failed_unreachable( +noreturn void log_assert_failed_unreachable_realm( + LogRealm realm, const char *text, const char *file, int line, const char *func); +#define log_assert_failed_unreachable(text, ...) \ + log_assert_failed_unreachable_realm(LOG_REALM, (text), __VA_ARGS__) -void log_assert_failed_return( +void log_assert_failed_return_realm( + LogRealm realm, const char *text, const char *file, int line, const char *func); +#define log_assert_failed_return(text, ...) \ + log_assert_failed_return_realm(LOG_REALM, (text), __VA_ARGS__) #define log_dispatch(level, error, buffer) \ log_dispatch_internal(level, error, __FILE__, __LINE__, __func__, NULL, NULL, NULL, NULL, buffer) /* Logging with level */ -#define log_full_errno(level, error, ...) \ +#define log_full_errno_realm(realm, level, error, ...) \ ({ \ int _level = (level), _e = (error); \ - (log_get_max_level() >= LOG_PRI(_level)) \ - ? log_internal(_level, _e, __FILE__, __LINE__, __func__, __VA_ARGS__) \ + (log_get_max_level_realm((realm)) >= LOG_PRI(_level)) \ + ? log_internal_realm(LOG_REALM_PLUS_LEVEL((realm), _level), _e, \ + __FILE__, __LINE__, __func__, __VA_ARGS__) \ : -abs(_e); \ }) -#define log_full(level, ...) log_full_errno(level, 0, __VA_ARGS__) +#define log_full_errno(level, error, ...) \ + log_full_errno_realm(LOG_REALM, (level), (error), __VA_ARGS__) + +#define log_full(level, ...) log_full_errno((level), 0, __VA_ARGS__) /* Normal logging */ #define log_debug(...) log_full(LOG_DEBUG, __VA_ARGS__) @@ -216,13 +259,17 @@ void log_assert_failed_return( #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__) +#define log_struct_errno(level, error, ...) \ + log_struct_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \ + error, __FILE__, __LINE__, __func__, __VA_ARGS__) +#define log_struct(level, ...) log_struct_errno(level, 0, __VA_ARGS__) /* This modifies the buffer passed! */ -#define log_dump(level, buffer) log_dump_internal(level, 0, __FILE__, __LINE__, __func__, buffer) +#define log_dump(level, buffer) \ + log_dump_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \ + 0, __FILE__, __LINE__, __func__, buffer) -#define log_oom() log_oom_internal(__FILE__, __LINE__, __func__) +#define log_oom() log_oom_internal(LOG_REALM, __FILE__, __LINE__, __func__) bool log_on_console(void) _pure_; diff --git a/src/test/test-log.c b/src/test/test-log.c index ae9e113..626d2c6 100644 --- a/src/test/test-log.c +++ b/src/test/test-log.c @@ -24,6 +24,15 @@ #include "log.h" #include "util.h" +assert_cc(LOG_REALM_REMOVE_LEVEL(LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, LOG_FTP | LOG_DEBUG)) + == LOG_REALM_SYSTEMD); +assert_cc(LOG_REALM_REMOVE_LEVEL(LOG_REALM_PLUS_LEVEL(LOG_REALM_UDEV, LOG_LOCAL7 | LOG_DEBUG)) + == LOG_REALM_UDEV); +assert_cc((LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, LOG_LOCAL3 | LOG_DEBUG) & LOG_FACMASK) + == LOG_LOCAL3); +assert_cc((LOG_REALM_PLUS_LEVEL(LOG_REALM_UDEV, LOG_USER | LOG_INFO) & LOG_PRIMASK) + == LOG_INFO); + int main(int argc, char* argv[]) { log_set_target(LOG_TARGET_CONSOLE); -- 2.7.4