diff --git a/man/systemd-socket-activate.xml b/man/systemd-socket-activate.xml
index f3dbb47a61..20a5572192 100644
--- a/man/systemd-socket-activate.xml
+++ b/man/systemd-socket-activate.xml
@@ -141,6 +141,7 @@
$SYSTEMD_LOG_TARGET
$SYSTEMD_LOG_LEVEL
+ $SYSTEMD_LOG_TIME
$SYSTEMD_LOG_COLOR
$SYSTEMD_LOG_LOCATION
diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml
index 3e6742ce2c..435c3882db 100644
--- a/man/systemd-system.conf.xml
+++ b/man/systemd-system.conf.xml
@@ -67,6 +67,7 @@
LogLevel=
LogLocation=
LogTarget=
+ LogTime=
DumpCore=yes
CrashChangeVT=no
CrashShell=no
diff --git a/man/systemd.xml b/man/systemd.xml
index 16f896a9eb..92d2708e4f 100644
--- a/man/systemd.xml
+++ b/man/systemd.xml
@@ -634,6 +634,13 @@
.
+
+ $SYSTEMD_LOG_TIME
+ Controls whether systemd prefixes log
+ messages with the current time. This can be overridden with
+ .
+
+
$XDG_CONFIG_HOME
$XDG_CONFIG_DIRS
@@ -826,14 +833,17 @@
systemd.log_level=
systemd.log_location
systemd.log_target=
+ systemd.log_time
Controls log output, with the same effect as the
$SYSTEMD_LOG_COLOR,
$SYSTEMD_LOG_LEVEL,
$SYSTEMD_LOG_LOCATION,
- $SYSTEMD_LOG_TARGET, environment variables described above.
- systemd.log_color and systemd.log_location can be
- specified without an argument, with the same effect as a positive boolean.
+ $SYSTEMD_LOG_TARGET,
+ $SYSTEMD_LOG_TIME, environment variables described above.
+ systemd.log_color, systemd.log_location, and
+ systemd.log_time can be specified without an argument, with the
+ same effect as a positive boolean.
@@ -1153,6 +1163,13 @@
Set log target. See systemd.log_target above.
+
+
+
+ Prefix messages with timestamp. See systemd.log_time above.
+
+
+
diff --git a/src/basic/log.c b/src/basic/log.c
index 17557e1844..ca024d970e 100644
--- a/src/basic/log.c
+++ b/src/basic/log.c
@@ -51,6 +51,7 @@ static bool syslog_is_stream = false;
static bool show_color = false;
static bool show_location = false;
+static bool show_time = false;
static bool upgrade_syslog_to_journal = false;
static bool always_reopen_console = false;
@@ -332,8 +333,10 @@ static int write_to_console(
const char *func,
const char *buffer) {
- char location[256], prefix[1 + DECIMAL_STR_MAX(int) + 2];
- struct iovec iovec[6] = {};
+ char location[256],
+ header_time[FORMAT_TIMESTAMP_MAX],
+ prefix[1 + DECIMAL_STR_MAX(int) + 2];
+ struct iovec iovec[8] = {};
const char *on = NULL, *off = NULL;
size_t n = 0;
@@ -345,6 +348,13 @@ static int write_to_console(
iovec[n++] = IOVEC_MAKE_STRING(prefix);
}
+ if (show_time) {
+ if (format_timestamp(header_time, sizeof(header_time), now(CLOCK_REALTIME))) {
+ iovec[n++] = IOVEC_MAKE_STRING(header_time);
+ iovec[n++] = IOVEC_MAKE_STRING(" ");
+ }
+ }
+
if (show_color)
get_log_colors(LOG_PRI(level), &on, &off, NULL);
@@ -1099,6 +1109,12 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
if (log_show_location_from_string(value ?: "1") < 0)
log_warning("Failed to parse log location setting '%s'. Ignoring.", value);
+
+ } else if (proc_cmdline_key_streq(key, "systemd.log_time")) {
+
+ if (log_show_time_from_string(value ?: "1") < 0)
+ log_warning("Failed to parse log time setting '%s'. Ignoring.", value);
+
}
return 0;
@@ -1130,6 +1146,10 @@ void log_parse_environment_realm(LogRealm realm) {
e = getenv("SYSTEMD_LOG_LOCATION");
if (e && log_show_location_from_string(e) < 0)
log_warning("Failed to parse log location '%s'. Ignoring.", e);
+
+ e = getenv("SYSTEMD_LOG_TIME");
+ if (e && log_show_time_from_string(e) < 0)
+ log_warning("Failed to parse log time '%s'. Ignoring.", e);
}
LogTarget log_get_target(void) {
@@ -1156,6 +1176,14 @@ bool log_get_show_location(void) {
return show_location;
}
+void log_show_time(bool b) {
+ show_time = b;
+}
+
+bool log_get_show_time(void) {
+ return show_time;
+}
+
int log_show_color_from_string(const char *e) {
int t;
@@ -1178,6 +1206,17 @@ int log_show_location_from_string(const char *e) {
return 0;
}
+int log_show_time_from_string(const char *e) {
+ int t;
+
+ t = parse_boolean(e);
+ if (t < 0)
+ return t;
+
+ log_show_time(t);
+ return 0;
+}
+
bool log_on_console(void) {
if (IN_SET(log_target, LOG_TARGET_CONSOLE,
LOG_TARGET_CONSOLE_PREFIXED))
diff --git a/src/basic/log.h b/src/basic/log.h
index 625be22402..4cec988364 100644
--- a/src/basic/log.h
+++ b/src/basic/log.h
@@ -59,9 +59,12 @@ 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_;
+void log_show_time(bool b);
+bool log_get_show_time(void) _pure_;
int log_show_color_from_string(const char *e);
int log_show_location_from_string(const char *e);
+int log_show_time_from_string(const char *e);
LogTarget log_get_target(void) _pure_;
int log_get_max_level_realm(LogRealm realm) _pure_;
diff --git a/src/core/main.c b/src/core/main.c
index 23a8ada1ec..fa91c6d81d 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -545,8 +545,9 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
DEFINE_SETTER(config_parse_level2, log_set_max_level_from_string, "log level");
DEFINE_SETTER(config_parse_target, log_set_target_from_string, "target");
-DEFINE_SETTER(config_parse_color, log_show_color_from_string, "color" );
+DEFINE_SETTER(config_parse_color, log_show_color_from_string, "color");
DEFINE_SETTER(config_parse_location, log_show_location_from_string, "location");
+DEFINE_SETTER(config_parse_time, log_show_time_from_string, "time");
static int config_parse_default_timeout_abort(
const char *unit,
@@ -574,6 +575,7 @@ static int parse_config_file(void) {
{ "Manager", "LogTarget", config_parse_target, 0, NULL },
{ "Manager", "LogColor", config_parse_color, 0, NULL },
{ "Manager", "LogLocation", config_parse_location, 0, NULL },
+ { "Manager", "LogTime", config_parse_time, 0, NULL },
{ "Manager", "DumpCore", config_parse_bool, 0, &arg_dump_core },
{ "Manager", "CrashChVT", /* legacy */ config_parse_crash_chvt, 0, &arg_crash_chvt },
{ "Manager", "CrashChangeVT", config_parse_crash_chvt, 0, &arg_crash_chvt },
@@ -721,6 +723,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_LOG_TARGET,
ARG_LOG_COLOR,
ARG_LOG_LOCATION,
+ ARG_LOG_TIME,
ARG_UNIT,
ARG_SYSTEM,
ARG_USER,
@@ -748,6 +751,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "log-target", required_argument, NULL, ARG_LOG_TARGET },
{ "log-color", optional_argument, NULL, ARG_LOG_COLOR },
{ "log-location", optional_argument, NULL, ARG_LOG_LOCATION },
+ { "log-time", optional_argument, NULL, ARG_LOG_TIME },
{ "unit", required_argument, NULL, ARG_UNIT },
{ "system", no_argument, NULL, ARG_SYSTEM },
{ "user", no_argument, NULL, ARG_USER },
@@ -821,6 +825,18 @@ static int parse_argv(int argc, char *argv[]) {
break;
+ case ARG_LOG_TIME:
+
+ if (optarg) {
+ r = log_show_time_from_string(optarg);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse log time setting \"%s\": %m",
+ optarg);
+ } else
+ log_show_time(true);
+
+ break;
+
case ARG_DEFAULT_STD_OUTPUT:
r = exec_output_from_string(optarg);
if (r < 0)
@@ -1042,6 +1058,7 @@ static int help(void) {
" --log-level=LEVEL Set log level (debug, info, notice, warning, err, crit, alert, emerg)\n"
" --log-color[=BOOL] Highlight important log messages\n"
" --log-location[=BOOL] Include code location in log messages\n"
+ " --log-time[=BOOL] Prefix log messages with current time\n"
" --default-standard-output= Set default standard output for services\n"
" --default-standard-error= Set default standard error output for services\n"
"\nSee the %s for details.\n"
@@ -1424,6 +1441,9 @@ static int become_shutdown(
if (log_get_show_location())
command_line[pos++] = "--log-location";
+ if (log_get_show_time())
+ command_line[pos++] = "--log-time";
+
if (streq(shutdown_verb, "exit")) {
command_line[pos++] = "--exit-code";
command_line[pos++] = exit_code;
diff --git a/src/core/system.conf.in b/src/core/system.conf.in
index 8112125468..40bb548887 100644
--- a/src/core/system.conf.in
+++ b/src/core/system.conf.in
@@ -16,6 +16,7 @@
#LogTarget=journal-or-kmsg
#LogColor=yes
#LogLocation=no
+#LogTime=no
#DumpCore=yes
#ShowStatus=yes
#CrashChangeVT=no
diff --git a/src/core/user.conf.in b/src/core/user.conf.in
index 95a162e0f6..bbe06319c9 100644
--- a/src/core/user.conf.in
+++ b/src/core/user.conf.in
@@ -15,6 +15,7 @@
#LogTarget=console
#LogColor=yes
#LogLocation=no
+#LogTime=no
#SystemCallArchitectures=
#TimerSlackNSec=
#StatusUnitFormat=@STATUS_UNIT_FORMAT_DEFAULT@
diff --git a/src/shutdown/shutdown.c b/src/shutdown/shutdown.c
index 15e6c1799e..c405ab9744 100644
--- a/src/shutdown/shutdown.c
+++ b/src/shutdown/shutdown.c
@@ -51,6 +51,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_LOG_TARGET,
ARG_LOG_COLOR,
ARG_LOG_LOCATION,
+ ARG_LOG_TIME,
ARG_EXIT_CODE,
ARG_TIMEOUT,
};
@@ -60,6 +61,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "log-target", required_argument, NULL, ARG_LOG_TARGET },
{ "log-color", optional_argument, NULL, ARG_LOG_COLOR },
{ "log-location", optional_argument, NULL, ARG_LOG_LOCATION },
+ { "log-time", optional_argument, NULL, ARG_LOG_TIME },
{ "exit-code", required_argument, NULL, ARG_EXIT_CODE },
{ "timeout", required_argument, NULL, ARG_TIMEOUT },
{}
@@ -110,6 +112,17 @@ static int parse_argv(int argc, char *argv[]) {
break;
+ case ARG_LOG_TIME:
+
+ if (optarg) {
+ r = log_show_time_from_string(optarg);
+ if (r < 0)
+ log_error_errno(r, "Failed to parse log time setting %s, ignoring: %m", optarg);
+ } else
+ log_show_time(true);
+
+ break;
+
case ARG_EXIT_CODE:
r = safe_atou8(optarg, &arg_exit_code);
if (r < 0)