journal: log filtering options support in PID1

Define new unit parameter (LogFilterPatterns) to filter logs processed by
journald.

This option is used to store a regular expression which is carried from
PID1 to systemd-journald through a cgroup xattrs:
`user.journald_log_filter_patterns`.
This commit is contained in:
Quentin Deslandes
2022-12-15 09:57:39 +00:00
parent 96c648fecd
commit 523ea1237a
14 changed files with 339 additions and 1 deletions
+51
View File
@@ -22,6 +22,7 @@
#include "load-fragment.h"
#include "macro.h"
#include "memory-util.h"
#include "pcre2-util.h"
#include "rm-rf.h"
#include "specifier.h"
#include "string-util.h"
@@ -997,6 +998,56 @@ TEST(unit_is_recursive_template_dependency) {
assert_se(unit_is_likely_recursive_template_dependency(u, "foobar@foobar@123.mount", "foobar@%n.mount") == 0);
}
#define TEST_PATTERN(_regex, _allowed_patterns_count, _denied_patterns_count) \
{ \
.regex = _regex, \
.allowed_patterns_count = _allowed_patterns_count, \
.denied_patterns_count = _denied_patterns_count \
}
TEST(config_parse_log_filter_patterns) {
ExecContext c = {};
int r;
static const struct {
const char *regex;
size_t allowed_patterns_count;
size_t denied_patterns_count;
} regex_tests[] = {
TEST_PATTERN("", 0, 0),
TEST_PATTERN(".*", 1, 0),
TEST_PATTERN("~.*", 1, 1),
TEST_PATTERN("", 0, 0),
TEST_PATTERN("~.*", 0, 1),
TEST_PATTERN("[.*", 0, 1), /* Invalid pattern. */
TEST_PATTERN(".*gg.*", 1, 1),
TEST_PATTERN("~.*", 1, 1), /* Already in the patterns list. */
TEST_PATTERN("[.*", 1, 1), /* Invalid pattern. */
TEST_PATTERN("\\x7ehello", 2, 1),
TEST_PATTERN("", 0, 0),
TEST_PATTERN("~foobar", 0, 1),
};
if (ERRNO_IS_NOT_SUPPORTED(dlopen_pcre2()))
return (void) log_tests_skipped("PCRE2 support is not available");
for (size_t i = 0; i < ELEMENTSOF(regex_tests); i++) {
r = config_parse_log_filter_patterns(NULL, "fake", 1, "section", 1, "LogFilterPatterns", 1,
regex_tests[i].regex, &c, NULL);
assert_se(r >= 0);
assert_se(set_size(c.log_filter_allowed_patterns) == regex_tests[i].allowed_patterns_count);
assert_se(set_size(c.log_filter_denied_patterns) == regex_tests[i].denied_patterns_count);
/* Ensure `~` is properly removed */
const char *p;
SET_FOREACH(p, c.log_filter_allowed_patterns)
assert_se(p && p[0] != '~');
SET_FOREACH(p, c.log_filter_denied_patterns)
assert_se(p && p[0] != '~');
}
}
static int intro(void) {
if (enter_cgroup_subroot(NULL) == -ENOMEDIUM)
return log_tests_skipped("cgroupfs not available");