service: add 'debug' option to RestartMode=
One of the major pait points of managing fleets of headless nodes is that when something fails at startup, unless debug level was already enabled (which usually isn't, as it's a firehose), one needs to manually enable it and pray the issue can be reproduced, which often is really hard and time consuming, just to get extra info. Usually the extra log messages are enough to triage an issue. This new option makes it so that when a service fails and is restarted due to Restart=, log level for that unit is set to debug, so that all setup code in pid1 and sd-executor logs at debug level, and also a new DEBUG_INVOCATION=1 env var is passed to the service itself, so that it knows it should start with a higher log level. Once the unit succeeds or reaches the rate limit the original level is restored.
This commit is contained in:
committed by
Luca Boccassi
parent
23e3bddc48
commit
7d8bbfbe08
+22
-7
@@ -3830,6 +3830,7 @@ void unit_reset_failed(Unit *u) {
|
||||
|
||||
ratelimit_reset(&u->start_ratelimit);
|
||||
u->start_limit_hit = false;
|
||||
u->debug_invocation = false;
|
||||
}
|
||||
|
||||
Unit *unit_following(Unit *u) {
|
||||
@@ -5406,6 +5407,8 @@ int unit_set_exec_params(Unit *u, ExecParameters *p) {
|
||||
if (!p->unit_id)
|
||||
return -ENOMEM;
|
||||
|
||||
p->debug_invocation = u->debug_invocation;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -5606,23 +5609,25 @@ static int unit_export_invocation_id(Unit *u) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int unit_export_log_level_max(Unit *u, const ExecContext *c) {
|
||||
static int unit_export_log_level_max(Unit *u, int log_level_max, bool overwrite) {
|
||||
const char *p;
|
||||
char buf[2];
|
||||
int r;
|
||||
|
||||
assert(u);
|
||||
assert(c);
|
||||
|
||||
if (u->exported_log_level_max)
|
||||
/* When the debug_invocation logic runs, overwrite will be true as we always want to switch the max
|
||||
* log level that the journal applies, and we want to always restore the previous level once done */
|
||||
|
||||
if (!overwrite && u->exported_log_level_max)
|
||||
return 0;
|
||||
|
||||
if (c->log_level_max < 0)
|
||||
if (log_level_max < 0)
|
||||
return 0;
|
||||
|
||||
assert(c->log_level_max <= 7);
|
||||
assert(log_level_max <= 7);
|
||||
|
||||
buf[0] = '0' + c->log_level_max;
|
||||
buf[0] = '0' + log_level_max;
|
||||
buf[1] = 0;
|
||||
|
||||
p = strjoina("/run/systemd/units/log-level-max:", u->id);
|
||||
@@ -5772,7 +5777,7 @@ void unit_export_state_files(Unit *u) {
|
||||
|
||||
c = unit_get_exec_context(u);
|
||||
if (c) {
|
||||
(void) unit_export_log_level_max(u, c);
|
||||
(void) unit_export_log_level_max(u, c->log_level_max, /* overwrite= */ false);
|
||||
(void) unit_export_log_extra_fields(u, c);
|
||||
(void) unit_export_log_ratelimit_interval(u, c);
|
||||
(void) unit_export_log_ratelimit_burst(u, c);
|
||||
@@ -5830,6 +5835,16 @@ void unit_unlink_state_files(Unit *u) {
|
||||
}
|
||||
}
|
||||
|
||||
int unit_overwrite_log_level_max(Unit *u, int log_level_max) {
|
||||
assert(u);
|
||||
|
||||
if (!u->exported_log_level_max)
|
||||
return 0; /* Nothing to do */
|
||||
|
||||
/* Ensure that the new log level is exported for the journal, in place of the previous one */
|
||||
return unit_export_log_level_max(u, log_level_max, /* overwrite= */ true);
|
||||
}
|
||||
|
||||
int unit_prepare_exec(Unit *u) {
|
||||
int r;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user