<varlistentry>
<term><varname>LogLevelMax=</varname></term>
- <listitem><para>Configures filtering by log level of log messages generated by this unit. Takes a
- <command>syslog</command> log level, one of <option>emerg</option> (lowest log level, only highest priority
- messages), <option>alert</option>, <option>crit</option>, <option>err</option>, <option>warning</option>,
- <option>notice</option>, <option>info</option>, <option>debug</option> (highest log level, also lowest priority
- messages). See <citerefentry
+ <listitem><para>Sets the maximum log level for log messages generated by this unit. Takes a
+ <command>syslog</command> log level, one of <option>emerg</option> (lowest log level, only highest
+ priority messages), <option>alert</option>, <option>crit</option>, <option>err</option>,
+ <option>warning</option>, <option>notice</option>, <option>info</option>, <option>debug</option>
+ (highest log level, also lowest priority messages). See <citerefentry
project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry> for
- details. By default, no filtering is applied (i.e. the default maximum log level is <option>debug</option>). Use
- this option to configure the logging system to drop log messages of a specific service above the specified
- level. For example, set <varname>LogLevelMax=</varname><option>info</option> in order to turn off debug logging
- of a particularly chatty unit. Note that the configured level is applied to any log messages written by any
- of the processes belonging to this unit, as well as any log messages written by the system manager process
- (PID 1) in reference to this unit, sent via any supported logging protocol. The filtering is applied
- early in the logging pipeline, before any kind of further processing is done. Moreover, messages which pass
- through this filter successfully might still be dropped by filters applied at a later stage in the logging
- subsystem. For example, <varname>MaxLevelStore=</varname> configured in
- <citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> might
- prohibit messages of higher log levels to be stored on disk, even though the per-unit
+ details. By default, the maximum log level is not overridden.</para>
+
+ <para>This option can be used to configure the logging system to drop log messages of a specific
+ service above the specified level. For example, set
+ <varname>LogLevelMax=</varname><option>info</option> in order to turn off debug logging of a
+ particularly chatty unit. Alternatively, this option can be used to enable extra logging about a
+ specific unit by the system or user manager processes without changing the global log level for the
+ system or user manager processes by setting <varname>LogLevelMax=</varname><option>debug</option>.
+ </para>
+
+ <para>Note that the configured level is applied to any log messages written by any of the processes
+ belonging to this unit, as well as any log messages written by the system or user manager processes
+ in reference to this unit, sent via any supported logging protocol. The override is applied early in
+ the logging pipeline, before any kind of further processing is done. Moreover, messages which pass
+ through this filter successfully might still be dropped by filters applied at a later stage in the
+ logging subsystem. For example, <varname>MaxLevelStore=</varname> configured in
+ <citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ might prohibit messages of higher log levels to be stored on disk, even though the per-unit
<varname>LogLevelMax=</varname> permitted it to be processed.</para>
<xi:include href="version-info.xml" xpointer="v236"/></listitem>
return u && u->job && u->job->type == type;
}
+static inline int unit_get_log_level_max(const Unit *u) {
+ if (u) {
+ if (u->debug_invocation)
+ return LOG_DEBUG;
+
+ ExecContext *ec = unit_get_exec_context(u);
+ if (ec && ec->log_level_max >= 0)
+ return ec->log_level_max;
+ }
+
+ return log_get_max_level();
+}
+
static inline bool unit_log_level_test(const Unit *u, int level) {
assert(u);
- ExecContext *ec = unit_get_exec_context(u);
- return !ec || ec->log_level_max < 0 || ec->log_level_max >= LOG_PRI(level) || u->debug_invocation;
+ return LOG_PRI(level) <= unit_get_log_level_max(u);
}
/* unit_log_skip is for cases like ExecCondition= where a unit is considered "done"
({ \
const Unit *_u = (unit); \
const int _l = (level); \
- bool _do_log = !(log_get_max_level() < LOG_PRI(_l) || \
- (_u && !unit_log_level_test(_u, _l))); \
- const ExecContext *_c = _do_log && _u ? \
- unit_get_exec_context(_u) : NULL; \
+ LOG_CONTEXT_SET_LOG_LEVEL(unit_get_log_level_max(_u)); \
+ const ExecContext *_c = _u ? unit_get_exec_context(_u) : NULL; \
LOG_CONTEXT_PUSH_IOV(_c ? _c->log_extra_fields : NULL, \
_c ? _c->n_log_extra_fields : 0); \
- !_do_log ? -ERRNO_VALUE(error) : \
- _u ? log_object_internal(_l, error, PROJECT_FILE, __LINE__, __func__, unit_log_field(_u), _u->id, unit_invocation_log_field(_u), _u->invocation_id_string, ##__VA_ARGS__) : \
- log_internal(_l, error, PROJECT_FILE, __LINE__, __func__, ##__VA_ARGS__); \
+ _u ? log_object_internal(_l, error, PROJECT_FILE, __LINE__, __func__, unit_log_field(_u), _u->id, unit_invocation_log_field(_u), _u->invocation_id_string, ##__VA_ARGS__) : \
+ log_internal(_l, error, PROJECT_FILE, __LINE__, __func__, ##__VA_ARGS__); \
})
#define log_unit_full_errno(unit, level, error, ...) \
({ \
const Unit *_u = (unit); \
const int _l = (level); \
- bool _do_log = unit_log_level_test(_u, _l); \
- const ExecContext *_c = _do_log && _u ? \
- unit_get_exec_context(_u) : NULL; \
+ LOG_CONTEXT_SET_LOG_LEVEL(unit_get_log_level_max(_u)); \
+ const ExecContext *_c = _u ? unit_get_exec_context(_u) : NULL; \
LOG_CONTEXT_PUSH_IOV(_c ? _c->log_extra_fields : NULL, \
_c ? _c->n_log_extra_fields : 0); \
- _do_log ? \
- log_struct_errno(_l, error, __VA_ARGS__, LOG_UNIT_ID(_u)) : \
- -ERRNO_VALUE(error); \
+ log_struct_errno(_l, error, __VA_ARGS__, LOG_UNIT_ID(_u)); \
})
#define log_unit_struct(unit, level, ...) log_unit_struct_errno(unit, level, 0, __VA_ARGS__)
({ \
const Unit *_u = (unit); \
const int _l = (level); \
- bool _do_log = unit_log_level_test(_u, _l); \
- const ExecContext *_c = _do_log && _u ? \
- unit_get_exec_context(_u) : NULL; \
+ LOG_CONTEXT_SET_LOG_LEVEL(unit_get_log_level_max(_u)); \
+ const ExecContext *_c = _u ? unit_get_exec_context(_u) : NULL; \
LOG_CONTEXT_PUSH_IOV(_c ? _c->log_extra_fields : NULL, \
_c ? _c->n_log_extra_fields : 0); \
- _do_log ? \
- log_struct_iovec_errno(_l, error, iovec, n_iovec) : \
- -ERRNO_VALUE(error); \
+ log_struct_iovec_errno(_l, error, iovec, n_iovec); \
})
#define log_unit_struct_iovec(unit, level, iovec, n_iovec) log_unit_struct_iovec_errno(unit, level, 0, iovec, n_iovec)
LOG_CONTEXT_PUSH_KEY_VALUE(unit_log_field(u), u->id); \
LOG_CONTEXT_PUSH_KEY_VALUE(unit_invocation_log_field(u), u->invocation_id_string); \
LOG_CONTEXT_PUSH_IOV(c ? c->log_extra_fields : NULL, c ? c->n_log_extra_fields : 0); \
- LOG_CONTEXT_SET_LOG_LEVEL(c->log_level_max >= 0 ? c->log_level_max : log_get_max_level())
+ LOG_CONTEXT_SET_LOG_LEVEL(unit_get_log_level_max(u))
#define LOG_CONTEXT_PUSH_UNIT(unit) \
_LOG_CONTEXT_PUSH_UNIT(unit, UNIQ_T(u, UNIQ), UNIQ_T(c, UNIQ))