journalctl: implement --facility=foo

Fixes #9716.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2020-02-27 21:36:42 +01:00
parent aa73f181e9
commit 196dedd503
2 changed files with 88 additions and 0 deletions

View File

@ -597,6 +597,16 @@
priorities.</para></listitem> priorities.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>--facility=</option></term>
<listitem><para>Filter output by syslog facility. Takes a comma-separated list of numbers or facility
names. The names are the usual syslog facilities as documented in
<citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
<option>--facility=help</option> may be used to display a list of known facility names and exit.
</para></listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><option>-g</option></term> <term><option>-g</option></term>
<term><option>--grep=</option></term> <term><option>--grep=</option></term>

View File

@ -62,6 +62,7 @@
#include "sigbus.h" #include "sigbus.h"
#include "string-table.h" #include "string-table.h"
#include "strv.h" #include "strv.h"
#include "stdio-util.h"
#include "syslog-util.h" #include "syslog-util.h"
#include "terminal-util.h" #include "terminal-util.h"
#include "tmpfile-util.h" #include "tmpfile-util.h"
@ -101,6 +102,7 @@ static const char *arg_directory = NULL;
static char **arg_file = NULL; static char **arg_file = NULL;
static bool arg_file_stdin = false; static bool arg_file_stdin = false;
static int arg_priorities = 0xFF; static int arg_priorities = 0xFF;
static Set *arg_facilities = NULL;
static char *arg_verify_key = NULL; static char *arg_verify_key = NULL;
#if HAVE_GCRYPT #if HAVE_GCRYPT
static usec_t arg_interval = DEFAULT_FSS_INTERVAL_USEC; static usec_t arg_interval = DEFAULT_FSS_INTERVAL_USEC;
@ -303,6 +305,21 @@ static int parse_boot_descriptor(const char *x, sd_id128_t *boot_id, int *offset
return 1; return 1;
} }
static int help_facilities(void) {
if (!arg_quiet)
puts("Available facilities:");
for (int i = 0; i < LOG_NFACILITIES; i++) {
_cleanup_free_ char *t = NULL;
if (log_facility_unshifted_to_string_alloc(i, &t))
return log_oom();
puts(t);
}
return 0;
}
static int help(void) { static int help(void) {
_cleanup_free_ char *link = NULL; _cleanup_free_ char *link = NULL;
int r; int r;
@ -332,6 +349,7 @@ static int help(void) {
" --user-unit=UNIT Show logs from the specified user unit\n" " --user-unit=UNIT Show logs from the specified user unit\n"
" -t --identifier=STRING Show entries with the specified syslog identifier\n" " -t --identifier=STRING Show entries with the specified syslog identifier\n"
" -p --priority=RANGE Show entries with the specified priority\n" " -p --priority=RANGE Show entries with the specified priority\n"
" --facility=FACILITY... Show entries with the specified facilities\n"
" -g --grep=PATTERN Show entries with MESSAGE matching PATTERN\n" " -g --grep=PATTERN Show entries with MESSAGE matching PATTERN\n"
" --case-sensitive[=BOOL] Force case sensitive or insenstive matching\n" " --case-sensitive[=BOOL] Force case sensitive or insenstive matching\n"
" -e --pager-end Immediately jump to the end in the pager\n" " -e --pager-end Immediately jump to the end in the pager\n"
@ -404,6 +422,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_SYSTEM, ARG_SYSTEM,
ARG_ROOT, ARG_ROOT,
ARG_HEADER, ARG_HEADER,
ARG_FACILITY,
ARG_SETUP_KEYS, ARG_SETUP_KEYS,
ARG_FILE, ARG_FILE,
ARG_INTERVAL, ARG_INTERVAL,
@ -461,6 +480,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "header", no_argument, NULL, ARG_HEADER }, { "header", no_argument, NULL, ARG_HEADER },
{ "identifier", required_argument, NULL, 't' }, { "identifier", required_argument, NULL, 't' },
{ "priority", required_argument, NULL, 'p' }, { "priority", required_argument, NULL, 'p' },
{ "facility", required_argument, NULL, ARG_FACILITY },
{ "grep", required_argument, NULL, 'g' }, { "grep", required_argument, NULL, 'g' },
{ "case-sensitive", optional_argument, NULL, ARG_CASE_SENSITIVE }, { "case-sensitive", optional_argument, NULL, ARG_CASE_SENSITIVE },
{ "setup-keys", no_argument, NULL, ARG_SETUP_KEYS }, { "setup-keys", no_argument, NULL, ARG_SETUP_KEYS },
@ -832,6 +852,41 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
} }
case ARG_FACILITY: {
const char *p;
for (p = optarg;;) {
_cleanup_free_ char *fac = NULL;
int num;
r = extract_first_word(&p, &fac, ",", 0);
if (r < 0)
return log_error_errno(r, "Failed to parse facilities: %s", optarg);
if (r == 0)
break;
if (streq(fac, "help")) {
help_facilities();
return 0;
}
num = log_facility_unshifted_from_string(fac);
if (num < 0)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Bad --facility= argument \"%s\".", fac);
r = set_ensure_allocated(&arg_facilities, NULL);
if (r < 0)
return log_oom();
r = set_put(arg_facilities, INT_TO_PTR(num));
if (r < 0)
return log_oom();
}
break;
}
#if HAVE_PCRE2 #if HAVE_PCRE2
case 'g': case 'g':
arg_pattern = optarg; arg_pattern = optarg;
@ -1676,6 +1731,24 @@ static int add_priorities(sd_journal *j) {
return 0; return 0;
} }
static int add_facilities(sd_journal *j) {
void *p;
Iterator it;
int r;
SET_FOREACH(p, arg_facilities, it) {
char match[STRLEN("SYSLOG_FACILITY=") + DECIMAL_STR_MAX(int)];
xsprintf(match, "SYSLOG_FACILITY=%d", PTR_TO_INT(p));
r = sd_journal_add_match(j, match, strlen(match));
if (r < 0)
return log_error_errno(r, "Failed to add match: %m");
}
return 0;
}
static int add_syslog_identifier(sd_journal *j) { static int add_syslog_identifier(sd_journal *j) {
int r; int r;
char **i; char **i;
@ -2314,6 +2387,10 @@ int main(int argc, char *argv[]) {
if (r < 0) if (r < 0)
goto finish; goto finish;
r = add_facilities(j);
if (r < 0)
goto finish;
r = add_matches(j, argv + optind); r = add_matches(j, argv + optind);
if (r < 0) if (r < 0)
goto finish; goto finish;
@ -2681,6 +2758,7 @@ finish:
strv_free(arg_file); strv_free(arg_file);
set_free(arg_facilities);
strv_free(arg_syslog_identifier); strv_free(arg_syslog_identifier);
strv_free(arg_system_units); strv_free(arg_system_units);
strv_free(arg_user_units); strv_free(arg_user_units);