Merge pull request #12926 from keszybz/urlify-logs

Urlify CONFIG_FILE and improve SYSTEMD_LOG_LOCATION
This commit is contained in:
Lennart Poettering 2019-07-11 00:00:34 +02:00 committed by GitHub
commit 08945b59d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 163 additions and 83 deletions

3
TODO
View File

@ -134,9 +134,6 @@ Features:
sufficient to build a link by prefixing "http://" and suffixing the
CODE_FILE.
* when outputting log data with journalctl and the log data includes references
to configuration files (CONFIG_FILE=), create a clickable link for it.
* Augment MESSAGE_ID with MESSAGE_BASE, in a similar fashion so that we can
make clickable links from log messages carrying a MESSAGE_ID, that lead to
some explanatory text online.

View File

@ -29,6 +29,10 @@ substs.set('PROJECT_VERSION', meson.project_version())
# This is to be used instead of meson.source_root(), as the latter will return
# the wrong result when systemd is being built as a meson subproject
project_source_root = meson.current_source_dir()
relative_source_path = run_command('realpath',
'--relative-to=@0@'.format(meson.current_build_dir()),
project_source_root).stdout().strip()
conf.set_quoted('RELATIVE_SOURCE_PATH', relative_source_path)
want_ossfuzz = get_option('oss-fuzz')
want_libfuzzer = get_option('llvm-fuzz')

View File

@ -76,7 +76,7 @@ typedef struct {
#if ENABLE_DEBUG_HASHMAP
# define HASHMAP_DEBUG_PARAMS , const char *func, const char *file, int line
# define HASHMAP_DEBUG_SRC_ARGS , __func__, __FILE__, __LINE__
# define HASHMAP_DEBUG_SRC_ARGS , __func__, PROJECT_FILE, __LINE__
# define HASHMAP_DEBUG_PASS_ARGS , func, file, line
#else
# define HASHMAP_DEBUG_PARAMS

View File

@ -351,7 +351,13 @@ static int write_to_console(
get_log_colors(LOG_PRI(level), &on, &off, NULL);
if (show_location) {
(void) snprintf(location, sizeof location, "(%s:%i) ", file, line);
const char *lon = "", *loff = "";
if (show_color) {
lon = ANSI_HIGHLIGHT_YELLOW4;
loff = ANSI_NORMAL;
}
(void) snprintf(location, sizeof location, "%s%s:%i%s: ", lon, file, line, loff);
iovec[n++] = IOVEC_MAKE_STRING(location);
}
@ -1232,18 +1238,29 @@ int log_syntax_internal(
if (unit)
unit_fmt = getpid_cached() == 1 ? "UNIT=%s" : "USER_UNIT=%s";
if (config_file)
return log_struct_internal(
LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
error,
file, line, func,
"MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
"CONFIG_FILE=%s", config_file,
"CONFIG_LINE=%u", config_line,
LOG_MESSAGE("%s:%u: %s", config_file, config_line, buffer),
unit_fmt, unit,
NULL);
else if (unit)
if (config_file) {
if (config_line > 0)
return log_struct_internal(
LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
error,
file, line, func,
"MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
"CONFIG_FILE=%s", config_file,
"CONFIG_LINE=%u", config_line,
LOG_MESSAGE("%s:%u: %s", config_file, config_line, buffer),
unit_fmt, unit,
NULL);
else
return log_struct_internal(
LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
error,
file, line, func,
"MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
"CONFIG_FILE=%s", config_file,
LOG_MESSAGE("%s: %s", config_file, buffer),
unit_fmt, unit,
NULL);
} else if (unit)
return log_struct_internal(
LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
error,

View File

@ -73,6 +73,9 @@ int log_get_max_level_realm(LogRealm realm) _pure_;
* for the application itself.
*/
assert_cc(STRLEN(__FILE__) > STRLEN(RELATIVE_SOURCE_PATH) + 1)
#define PROJECT_FILE (__FILE__ + STRLEN(RELATIVE_SOURCE_PATH) + 1)
int log_open(void);
void log_close(void);
void log_forget_fds(void);
@ -210,7 +213,7 @@ void log_assert_failed_return_realm(
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)
log_dispatch_internal(level, error, PROJECT_FILE, __LINE__, __func__, NULL, NULL, NULL, NULL, buffer)
/* Logging with level */
#define log_full_errno_realm(realm, level, error, ...) \
@ -218,7 +221,7 @@ void log_assert_failed_return_realm(
int _level = (level), _e = (error), _realm = (realm); \
(log_get_max_level_realm(_realm) >= LOG_PRI(_level)) \
? log_internal_realm(LOG_REALM_PLUS_LEVEL(_realm, _level), _e, \
__FILE__, __LINE__, __func__, __VA_ARGS__) \
PROJECT_FILE, __LINE__, __func__, __VA_ARGS__) \
: -ERRNO_VALUE(_e); \
})
@ -254,20 +257,20 @@ int log_emergency_level(void);
/* Structured logging */
#define log_struct_errno(level, error, ...) \
log_struct_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \
error, __FILE__, __LINE__, __func__, __VA_ARGS__, NULL)
error, PROJECT_FILE, __LINE__, __func__, __VA_ARGS__, NULL)
#define log_struct(level, ...) log_struct_errno(level, 0, __VA_ARGS__)
#define log_struct_iovec_errno(level, error, iovec, n_iovec) \
log_struct_iovec_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \
error, __FILE__, __LINE__, __func__, iovec, n_iovec)
error, PROJECT_FILE, __LINE__, __func__, iovec, n_iovec)
#define log_struct_iovec(level, iovec, n_iovec) log_struct_iovec_errno(level, 0, iovec, n_iovec)
/* This modifies the buffer passed! */
#define log_dump(level, buffer) \
log_dump_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \
0, __FILE__, __LINE__, __func__, buffer)
0, PROJECT_FILE, __LINE__, __func__, buffer)
#define log_oom() log_oom_internal(LOG_REALM, __FILE__, __LINE__, __func__)
#define log_oom() log_oom_internal(LOG_REALM, PROJECT_FILE, __LINE__, __func__)
bool log_on_console(void) _pure_;
@ -320,7 +323,7 @@ int log_syntax_invalid_utf8_internal(
({ \
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__) \
? log_syntax_internal(unit, _level, config_file, config_line, _e, PROJECT_FILE, __LINE__, __func__, __VA_ARGS__) \
: -ERRNO_VALUE(_e); \
})
@ -328,7 +331,7 @@ int log_syntax_invalid_utf8_internal(
({ \
int _level = (level); \
(log_get_max_level() >= LOG_PRI(_level)) \
? log_syntax_invalid_utf8_internal(unit, _level, config_file, config_line, __FILE__, __LINE__, __func__, rvalue) \
? log_syntax_invalid_utf8_internal(unit, _level, config_file, config_line, PROJECT_FILE, __LINE__, __func__, rvalue) \
: -EINVAL; \
})

View File

@ -324,12 +324,12 @@ static inline int __coverity_check__(int condition) {
#define assert_message_se(expr, message) \
do { \
if (_unlikely_(!(expr))) \
log_assert_failed(message, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
log_assert_failed(message, PROJECT_FILE, __LINE__, __PRETTY_FUNCTION__); \
} while (false)
#define assert_log(expr, message) ((_likely_(expr)) \
? (true) \
: (log_assert_failed_return(message, __FILE__, __LINE__, __PRETTY_FUNCTION__), false))
: (log_assert_failed_return(message, PROJECT_FILE, __LINE__, __PRETTY_FUNCTION__), false))
#endif /* __COVERITY__ */
@ -345,7 +345,7 @@ static inline int __coverity_check__(int condition) {
#define assert_not_reached(t) \
do { \
log_assert_failed_unreachable(t, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
log_assert_failed_unreachable(t, PROJECT_FILE, __LINE__, __PRETTY_FUNCTION__); \
} while (false)
#if defined(static_assert)

View File

@ -19,12 +19,13 @@
#define ANSI_GREY "\x1B[0;38;5;245m"
/* Bold/highlighted */
#define ANSI_HIGHLIGHT_RED "\x1B[0;1;31m"
#define ANSI_HIGHLIGHT_GREEN "\x1B[0;1;32m"
#define ANSI_HIGHLIGHT_YELLOW "\x1B[0;1;38;5;185m"
#define ANSI_HIGHLIGHT_BLUE "\x1B[0;1;34m"
#define ANSI_HIGHLIGHT_MAGENTA "\x1B[0;1;35m"
#define ANSI_HIGHLIGHT_GREY "\x1B[0;1;38;5;245m"
#define ANSI_HIGHLIGHT_RED "\x1B[0;1;31m"
#define ANSI_HIGHLIGHT_GREEN "\x1B[0;1;32m"
#define ANSI_HIGHLIGHT_YELLOW "\x1B[0;1;38;5;185m"
#define ANSI_HIGHLIGHT_BLUE "\x1B[0;1;34m"
#define ANSI_HIGHLIGHT_MAGENTA "\x1B[0;1;35m"
#define ANSI_HIGHLIGHT_GREY "\x1B[0;1;38;5;245m"
#define ANSI_HIGHLIGHT_YELLOW4 "\x1B[0;1;38;5;100m"
/* Underlined */
#define ANSI_HIGHLIGHT_RED_UNDERLINE "\x1B[0;1;4;31m"

View File

@ -127,7 +127,7 @@ _printf_(2, 3) static int log_callback(int type, const char *fmt, ...) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
log_internalv(LOG_AUTH | callback_type_to_priority(type),
0, __FILE__, __LINE__, __FUNCTION__,
0, PROJECT_FILE, __LINE__, __FUNCTION__,
fmt2, ap);
#pragma GCC diagnostic pop
va_end(ap);

View File

@ -858,8 +858,8 @@ int unit_test_trigger_loaded(Unit *u);
#define log_unit_full(unit, level, error, ...) \
({ \
const Unit *_u = (unit); \
_u ? log_object_internal(level, error, __FILE__, __LINE__, __func__, _u->manager->unit_log_field, _u->id, _u->manager->invocation_log_field, _u->invocation_id_string, ##__VA_ARGS__) : \
log_internal(level, error, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \
_u ? log_object_internal(level, error, PROJECT_FILE, __LINE__, __func__, _u->manager->unit_log_field, _u->id, _u->manager->invocation_log_field, _u->invocation_id_string, ##__VA_ARGS__) : \
log_internal(level, error, PROJECT_FILE, __LINE__, __func__, ##__VA_ARGS__); \
})
#define log_unit_debug(unit, ...) log_unit_full(unit, LOG_DEBUG, 0, ##__VA_ARGS__)

View File

@ -30,7 +30,7 @@ _noreturn_ static void log_assert_errno(const char *text, int error, const char
do { \
int _r_ = (expr); \
if (_unlikely_(_r_ < 0)) \
log_assert_errno(#expr, -_r_, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
log_assert_errno(#expr, -_r_, PROJECT_FILE, __LINE__, __PRETTY_FUNCTION__); \
} while (false)
static JournalFile *test_open(const char *name) {

View File

@ -51,5 +51,5 @@ int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum, ui
#define DHCP_CLIENT_DONT_DESTROY(client) \
_cleanup_(sd_dhcp_client_unrefp) _unused_ sd_dhcp_client *_dont_destroy_##client = sd_dhcp_client_ref(client)
#define log_dhcp_client_errno(client, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__)
#define log_dhcp_client_errno(client, error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__)
#define log_dhcp_client(client, fmt, ...) log_dhcp_client_errno(client, 0, fmt, ##__VA_ARGS__)

View File

@ -69,8 +69,8 @@ typedef struct DHCPRequest {
uint32_t lifetime;
} DHCPRequest;
#define log_dhcp_server(client, fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "DHCP SERVER: " fmt, ##__VA_ARGS__)
#define log_dhcp_server_errno(client, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "DHCP SERVER: " fmt, ##__VA_ARGS__)
#define log_dhcp_server(client, fmt, ...) log_internal(LOG_DEBUG, 0, PROJECT_FILE, __LINE__, __func__, "DHCP SERVER: " fmt, ##__VA_ARGS__)
#define log_dhcp_server_errno(client, error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "DHCP SERVER: " fmt, ##__VA_ARGS__)
int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
size_t length);

View File

@ -79,7 +79,7 @@ struct DHCP6IA {
typedef struct DHCP6IA DHCP6IA;
#define log_dhcp6_client_errno(p, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__)
#define log_dhcp6_client_errno(p, error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__)
#define log_dhcp6_client(p, fmt, ...) log_dhcp6_client_errno(p, 0, fmt, ##__VA_ARGS__)
int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,

View File

@ -32,7 +32,7 @@ struct sd_lldp {
struct ether_addr filter_address;
};
#define log_lldp_errno(error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "LLDP: " fmt, ##__VA_ARGS__)
#define log_lldp_errno(error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "LLDP: " fmt, ##__VA_ARGS__)
#define log_lldp(fmt, ...) log_lldp_errno(0, fmt, ##__VA_ARGS__)
const char* lldp_event_to_string(sd_lldp_event e) _const_;

View File

@ -37,7 +37,7 @@ struct sd_ndisc {
void *userdata;
};
#define log_ndisc_errno(error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "NDISC: " fmt, ##__VA_ARGS__)
#define log_ndisc_errno(error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "NDISC: " fmt, ##__VA_ARGS__)
#define log_ndisc(fmt, ...) log_ndisc_errno(0, fmt, ##__VA_ARGS__)
const char* ndisc_event_to_string(sd_ndisc_event e) _const_;

View File

@ -98,6 +98,6 @@ struct sd_radv_prefix {
usec_t preferred_until;
};
#define log_radv_full(level, error, fmt, ...) log_internal(level, error, __FILE__, __LINE__, __func__, "RADV: " fmt, ##__VA_ARGS__)
#define log_radv_full(level, error, fmt, ...) log_internal(level, error, PROJECT_FILE, __LINE__, __func__, "RADV: " fmt, ##__VA_ARGS__)
#define log_radv_errno(error, fmt, ...) log_radv_full(LOG_DEBUG, error, fmt, ##__VA_ARGS__)
#define log_radv(fmt, ...) log_radv_errno(0, fmt, ##__VA_ARGS__)

View File

@ -72,7 +72,7 @@ struct sd_ipv4acd {
void* userdata;
};
#define log_ipv4acd_errno(acd, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "IPV4ACD: " fmt, ##__VA_ARGS__)
#define log_ipv4acd_errno(acd, error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "IPV4ACD: " fmt, ##__VA_ARGS__)
#define log_ipv4acd(acd, fmt, ...) log_ipv4acd_errno(acd, 0, fmt, ##__VA_ARGS__)
static void ipv4acd_set_state(sd_ipv4acd *acd, IPv4ACDState st, bool reset_counter) {

View File

@ -50,7 +50,7 @@ struct sd_ipv4ll {
void* userdata;
};
#define log_ipv4ll_errno(ll, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "IPV4LL: " fmt, ##__VA_ARGS__)
#define log_ipv4ll_errno(ll, error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "IPV4LL: " fmt, ##__VA_ARGS__)
#define log_ipv4ll(ll, fmt, ...) log_ipv4ll_errno(ll, 0, fmt, ##__VA_ARGS__)
static void ipv4ll_on_acd(sd_ipv4acd *ll, int event, void *userdata);

View File

@ -39,7 +39,7 @@
\
if (_d && _unlikely_(log_get_max_level() >= _level)) \
(void) sd_device_get_sysname(_d, &_sysname); \
log_object_internal(_level, _error, __FILE__, __LINE__, __func__, \
log_object_internal(_level, _error, PROJECT_FILE, __LINE__, __func__, \
_sysname ? "DEVICE=" : NULL, _sysname, \
NULL, NULL, ##__VA_ARGS__); \
})

View File

@ -193,8 +193,8 @@ const struct ConfigPerfItem* network_netdev_gperf_lookup(const char *key, GPERF_
#define log_netdev_full(netdev, level, error, ...) \
({ \
const NetDev *_n = (netdev); \
_n ? log_object_internal(level, error, __FILE__, __LINE__, __func__, "INTERFACE=", _n->ifname, NULL, NULL, ##__VA_ARGS__) : \
log_internal(level, error, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \
_n ? log_object_internal(level, error, PROJECT_FILE, __LINE__, __func__, "INTERFACE=", _n->ifname, NULL, NULL, ##__VA_ARGS__) : \
log_internal(level, error, PROJECT_FILE, __LINE__, __func__, ##__VA_ARGS__); \
})
#define log_netdev_debug(netdev, ...) log_netdev_full(netdev, LOG_DEBUG, 0, ##__VA_ARGS__)

View File

@ -788,14 +788,14 @@ bool condition_test_list(Condition *first, const char *(*to_string)(ConditionTyp
assert(p);
if (r < 0)
logger(userdata, LOG_WARNING, r, __FILE__, __LINE__, __func__,
logger(userdata, LOG_WARNING, r, PROJECT_FILE, __LINE__, __func__,
"Couldn't determine result for %s=%s%s%s, assuming failed: %m",
to_string(c->type),
c->trigger ? "|" : "",
c->negate ? "!" : "",
p);
else
logger(userdata, LOG_DEBUG, 0, __FILE__, __LINE__, __func__,
logger(userdata, LOG_DEBUG, 0, PROJECT_FILE, __LINE__, __func__,
"%s=%s%s%s %s.",
to_string(c->type),
c->trigger ? "|" : "",

View File

@ -271,7 +271,7 @@ int json_log_internal(JsonVariant *variant, int level, int error, const char *fi
({ \
int _level = json_dispatch_level(flags), _e = (error); \
(log_get_max_level() >= LOG_PRI(_level)) \
? json_log_internal(variant, _level, _e, __FILE__, __LINE__, __func__, __VA_ARGS__) \
? json_log_internal(variant, _level, _e, PROJECT_FILE, __LINE__, __func__, __VA_ARGS__) \
: -ERRNO_VALUE(_e); \
})

View File

@ -17,8 +17,8 @@
#define log_link_full(link, level, error, ...) \
({ \
const Link *_l = (link); \
(_l && _l->ifname) ? log_object_internal(level, error, __FILE__, __LINE__, __func__, "INTERFACE=", _l->ifname, NULL, NULL, ##__VA_ARGS__) : \
log_internal(level, error, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \
(_l && _l->ifname) ? log_object_internal(level, error, PROJECT_FILE, __LINE__, __func__, "INTERFACE=", _l->ifname, NULL, NULL, ##__VA_ARGS__) : \
log_internal(level, error, PROJECT_FILE, __LINE__, __func__, ##__VA_ARGS__); \
}) \
#define log_link_debug(link, ...) log_link_full(link, LOG_DEBUG, 0, ##__VA_ARGS__)

View File

@ -29,6 +29,7 @@
#include "output-mode.h"
#include "parse-util.h"
#include "process-util.h"
#include "pretty-print.h"
#include "sparse-endian.h"
#include "stdio-util.h"
#include "string-table.h"
@ -375,8 +376,8 @@ static int output_short(
const void *data;
size_t length;
size_t n = 0;
_cleanup_free_ char *hostname = NULL, *identifier = NULL, *comm = NULL, *pid = NULL, *fake_pid = NULL, *message = NULL, *realtime = NULL, *monotonic = NULL, *priority = NULL, *transport = NULL, *unit = NULL, *user_unit = NULL;
size_t hostname_len = 0, identifier_len = 0, comm_len = 0, pid_len = 0, fake_pid_len = 0, message_len = 0, realtime_len = 0, monotonic_len = 0, priority_len = 0, transport_len = 0, unit_len = 0, user_unit_len = 0;
_cleanup_free_ char *hostname = NULL, *identifier = NULL, *comm = NULL, *pid = NULL, *fake_pid = NULL, *message = NULL, *realtime = NULL, *monotonic = NULL, *priority = NULL, *transport = NULL, *config_file = NULL, *unit = NULL, *user_unit = NULL;
size_t hostname_len = 0, identifier_len = 0, comm_len = 0, pid_len = 0, fake_pid_len = 0, message_len = 0, realtime_len = 0, monotonic_len = 0, priority_len = 0, transport_len = 0, config_file_len = 0, unit_len = 0, user_unit_len = 0;
int p = LOG_INFO;
bool ellipsized = false, audit;
const ParseFieldVec fields[] = {
@ -390,6 +391,7 @@ static int output_short(
PARSE_FIELD_VEC_ENTRY("SYSLOG_IDENTIFIER=", &identifier, &identifier_len),
PARSE_FIELD_VEC_ENTRY("_SOURCE_REALTIME_TIMESTAMP=", &realtime, &realtime_len),
PARSE_FIELD_VEC_ENTRY("_SOURCE_MONOTONIC_TIMESTAMP=", &monotonic, &monotonic_len),
PARSE_FIELD_VEC_ENTRY("CONFIG_FILE=", &config_file, &config_file_len),
PARSE_FIELD_VEC_ENTRY("_SYSTEMD_UNIT=", &unit, &unit_len),
PARSE_FIELD_VEC_ENTRY("_SYSTEMD_USER_UNIT=", &user_unit, &user_unit_len),
};
@ -451,7 +453,8 @@ static int output_short(
n += hostname_len + 1;
}
if (mode == OUTPUT_WITH_UNIT && ((unit && shall_print(unit, unit_len, flags)) || (user_unit && shall_print(user_unit, user_unit_len, flags)))) {
if (mode == OUTPUT_WITH_UNIT && ((unit && shall_print(unit, unit_len, flags)) ||
(user_unit && shall_print(user_unit, user_unit_len, flags)))) {
if (unit) {
fprintf(f, " %.*s", (int) unit_len, unit);
n += unit_len + 1;
@ -485,6 +488,34 @@ static int output_short(
fprintf(f, ": [%s blob data]\n", format_bytes(bytes, sizeof(bytes), message_len));
} else {
fputs(": ", f);
/* URLify config_file string in message, if the message starts with it.
* Skip URLification if the highlighted pattern overlaps. */
if (config_file &&
message_len >= config_file_len &&
memcmp(message, config_file, config_file_len) == 0 &&
IN_SET(message[config_file_len], ':', ' ', '\0') &&
(!highlight || highlight_shifted[0] == 0 || highlight_shifted[0] > config_file_len)) {
_cleanup_free_ char *t = NULL, *urlified = NULL;
t = strndup(config_file, config_file_len);
if (t && terminal_urlify_path(t, NULL, &urlified) >= 0) {
size_t shift = strlen(urlified) - config_file_len;
char *joined;
joined = strjoin(urlified, message + config_file_len);
if (joined) {
free_and_replace(message, joined);
message_len += shift;
if (highlight) {
highlight_shifted[0] += shift;
highlight_shifted[1] += shift;
}
}
}
}
ellipsized |=
print_multiline(f, n + 2, n_columns, flags, p, audit,
message, message_len,
@ -556,9 +587,11 @@ static int output_verbose(
cursor);
JOURNAL_FOREACH_DATA_RETVAL(j, data, length, r) {
const char *c;
const char *c, *p;
int fieldlen;
const char *on = "", *off = "";
_cleanup_free_ char *urlified = NULL;
size_t valuelen;
c = memchr(data, '=', length);
if (!c)
@ -569,20 +602,28 @@ static int output_verbose(
r = field_set_test(output_fields, data, fieldlen);
if (r < 0)
return r;
if (!r)
if (r == 0)
continue;
if (flags & OUTPUT_COLOR && startswith(data, "MESSAGE=")) {
valuelen = length - 1 - fieldlen;
if ((flags & OUTPUT_COLOR) && (p = startswith(data, "MESSAGE="))) {
on = ANSI_HIGHLIGHT;
off = ANSI_NORMAL;
}
} else if ((p = startswith(data, "CONFIG_FILE="))) {
if (terminal_urlify_path(p, NULL, &urlified) >= 0) {
p = urlified;
valuelen = strlen(urlified);
}
} else
p = c + 1;
if ((flags & OUTPUT_SHOW_ALL) ||
(((length < PRINT_CHAR_THRESHOLD) || flags & OUTPUT_FULL_WIDTH)
&& utf8_is_printable(data, length))) {
fprintf(f, " %s%.*s=", on, fieldlen, (const char*)data);
print_multiline(f, 4 + fieldlen + 1, 0, OUTPUT_FULL_WIDTH, 0, false,
c + 1, length - fieldlen - 1,
p, valuelen,
NULL);
fputs(off, f);
} else {
@ -1040,21 +1081,21 @@ static int (*output_funcs[_OUTPUT_MODE_MAX])(
Set *output_fields,
const size_t highlight[2]) = {
[OUTPUT_SHORT] = output_short,
[OUTPUT_SHORT_ISO] = output_short,
[OUTPUT_SHORT] = output_short,
[OUTPUT_SHORT_ISO] = output_short,
[OUTPUT_SHORT_ISO_PRECISE] = output_short,
[OUTPUT_SHORT_PRECISE] = output_short,
[OUTPUT_SHORT_MONOTONIC] = output_short,
[OUTPUT_SHORT_UNIX] = output_short,
[OUTPUT_SHORT_FULL] = output_short,
[OUTPUT_VERBOSE] = output_verbose,
[OUTPUT_EXPORT] = output_export,
[OUTPUT_JSON] = output_json,
[OUTPUT_JSON_PRETTY] = output_json,
[OUTPUT_JSON_SSE] = output_json,
[OUTPUT_JSON_SEQ] = output_json,
[OUTPUT_CAT] = output_cat,
[OUTPUT_WITH_UNIT] = output_short,
[OUTPUT_SHORT_PRECISE] = output_short,
[OUTPUT_SHORT_MONOTONIC] = output_short,
[OUTPUT_SHORT_UNIX] = output_short,
[OUTPUT_SHORT_FULL] = output_short,
[OUTPUT_VERBOSE] = output_verbose,
[OUTPUT_EXPORT] = output_export,
[OUTPUT_JSON] = output_json,
[OUTPUT_JSON_PRETTY] = output_json,
[OUTPUT_JSON_SSE] = output_json,
[OUTPUT_JSON_SEQ] = output_json,
[OUTPUT_CAT] = output_cat,
[OUTPUT_WITH_UNIT] = output_short,
};
int show_journal_entry(

View File

@ -57,25 +57,29 @@ int udev_parse_config_full(
* to regulate the code in libudev/ and udev/. */
r = log_set_max_level_from_string_realm(LOG_REALM_UDEV, log);
if (r < 0)
log_debug_errno(r, "/etc/udev/udev.conf: failed to set udev log level '%s', ignoring: %m", log);
log_syntax(NULL, LOG_WARNING, "/etc/udev/udev.conf", 0, r,
"failed to set udev log level '%s', ignoring: %m", log);
}
if (ret_children_max && children_max) {
r = safe_atou(children_max, ret_children_max);
if (r < 0)
log_notice_errno(r, "/etc/udev/udev.conf: failed to set parse children_max=%s, ignoring: %m", children_max);
log_syntax(NULL, LOG_WARNING, "/etc/udev/udev.conf", 0, r,
"failed to set parse children_max=%s, ignoring: %m", children_max);
}
if (ret_exec_delay_usec && exec_delay) {
r = parse_sec(exec_delay, ret_exec_delay_usec);
if (r < 0)
log_notice_errno(r, "/etc/udev/udev.conf: failed to set parse exec_delay=%s, ignoring: %m", exec_delay);
log_syntax(NULL, LOG_WARNING, "/etc/udev/udev.conf", 0, r,
"failed to set parse exec_delay=%s, ignoring: %m", exec_delay);
}
if (ret_event_timeout_usec && event_timeout) {
r = parse_sec(event_timeout, ret_event_timeout_usec);
if (r < 0)
log_notice_errno(r, "/etc/udev/udev.conf: failed to set parse event_timeout=%s, ignoring: %m", event_timeout);
log_syntax(NULL, LOG_WARNING, "/etc/udev/udev.conf", 0, r,
"failed to set parse event_timeout=%s, ignoring: %m", event_timeout);
}
if (ret_resolve_name_timing && resolve_names) {
@ -83,7 +87,8 @@ int udev_parse_config_full(
t = resolve_name_timing_from_string(resolve_names);
if (t < 0)
log_notice("/etc/udev/udev.conf: failed to set parse resolve_names=%s, ignoring.", resolve_names);
log_syntax(NULL, LOG_WARNING, "/etc/udev/udev.conf", 0, r,
"failed to set parse resolve_names=%s, ignoring.", resolve_names);
else
*ret_resolve_name_timing = t;
}

View File

@ -6,6 +6,7 @@
#include "format-util.h"
#include "log.h"
#include "process-util.h"
#include "string-util.h"
#include "util.h"
assert_cc(LOG_REALM_REMOVE_LEVEL(LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, LOG_FTP | LOG_DEBUG))
@ -26,6 +27,14 @@ assert_cc(!IS_SYNTHETIC_ERRNO(0));
#define X100(x) X10(X10(x))
#define X1000(x) X100(X10(x))
static void test_file(void) {
log_info("__FILE__: %s", __FILE__);
log_info("RELATIVE_SOURCE_PATH: %s", RELATIVE_SOURCE_PATH);
log_info("PROJECT_FILE: %s", PROJECT_FILE);
assert(startswith(__FILE__, RELATIVE_SOURCE_PATH "/"));
}
static void test_log_struct(void) {
log_struct(LOG_INFO,
"MESSAGE=Waldo PID="PID_FMT" (no errno)", getpid_cached(),
@ -68,6 +77,8 @@ static void test_log_syntax(void) {
int main(int argc, char* argv[]) {
int target;
test_file();
for (target = 0; target < _LOG_TARGET_MAX; target++) {
log_set_target(target);
log_open();

View File

@ -1726,9 +1726,10 @@ static int run(int argc, char *argv[]) {
int r;
log_set_target(LOG_TARGET_AUTO);
log_open();
udev_parse_config_full(&arg_children_max, &arg_exec_delay_usec, &arg_event_timeout_usec, &arg_resolve_name_timing);
log_parse_environment();
log_open();
log_open(); /* Done again to update after reading configuration. */
r = parse_argv(argc, argv);
if (r <= 0)