From eb86030ec0e53ef3834d1b230440e88fdf020e9d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 27 Jan 2016 18:59:29 +0100 Subject: sd-journal: add an API to enumerate known field names of the journal This adds two new calls to get the list of all journal fields names currently in use. This is the low-level support to implement the feature requested in #2176 in a more optimized way. --- man/sd-journal.xml | 4 + man/sd_journal_enumerate_fields.xml | 161 ++++++++++++++++++++++++++++++++++++ man/sd_journal_query_unique.xml | 44 +++++----- 3 files changed, 190 insertions(+), 19 deletions(-) create mode 100644 man/sd_journal_enumerate_fields.xml (limited to 'man') diff --git a/man/sd-journal.xml b/man/sd-journal.xml index a1185d372b..09747a480c 100644 --- a/man/sd-journal.xml +++ b/man/sd-journal.xml @@ -77,6 +77,8 @@ sd_journal_get_realtime_usec3, sd_journal_add_match3, sd_journal_seek_head3, + sd_journal_query_enumerate3, + sd_journal_enumerate_fields3, sd_journal_get_cursor3, sd_journal_get_cutoff_realtime_usec3, sd_journal_get_cutoff_monotonic_usec3, @@ -111,6 +113,8 @@ sd_journal_get_realtime_usec3, sd_journal_add_match3, sd_journal_seek_head3, + sd_journal_query_enumerate3, + sd_journal_enumerate_fields3, sd_journal_get_cursor3, sd_journal_get_cutoff_realtime_usec3, sd_journal_get_cutoff_monotonic_usec3, diff --git a/man/sd_journal_enumerate_fields.xml b/man/sd_journal_enumerate_fields.xml new file mode 100644 index 0000000000..fa5884106b --- /dev/null +++ b/man/sd_journal_enumerate_fields.xml @@ -0,0 +1,161 @@ + + + + + + + + + sd_journal_enumerate_fields + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_journal_enumerate_fields + 3 + + + + sd_journal_enumerate_fields + sd_journal_restart_fields + SD_JOURNAL_FOREACH_FIELD + Read used field names from the journal + + + + + #include <systemd/sd-journal.h> + + + int sd_journal_enumerate_fields + sd_journal *j + const char **field + + + + void sd_journal_restart_fields + sd_journal *j + + + + SD_JOURNAL_FOREACH_FIELD + sd_journal *j + const char *field + + + + + + + Description + + sd_journal_enumerate_fields() may be used to iterate through all field names used in the + opened journal files. On each invocation the next field name is returned. The order of the returned field names is + not defined. It takes two arguments: the journal context object, plus a pointer to a constant string pointer where + the field name is stored in. The returned data is in a read-only memory map and is only valid until the next + invocation of sd_journal_enumerate_fields(). Note that this call is subject to the data field + size threshold as controlled by sd_journal_set_data_threshold(). + + sd_journal_restart_fields() resets the field name enumeration index to the beginning of + the list. The next invocation of sd_journal_enumerate_fields() will return the first field + name again. + + The SD_JOURNAL_FOREACH_FIELD() macro may be used as a handy wrapper around + sd_journal_restart_fields() and sd_journal_enumerate_fields(). + + These functions currently are not influenced by matches set with sd_journal_add_match() + but this might change in a later version of this software. + + To retrieve the possible values a specific field can take use + sd_journal_query_unique3. + + + + Return Value + + sd_journal_enumerate_fields() returns a + positive integer if the next field name has been read, 0 when no + more field names are known, or a negative errno-style error code. + sd_journal_restart_fields() returns + nothing. + + + + Notes + + The sd_journal_enumerate_fields() and sd_journal_restart_fields() + interfaces are available as a shared library, which can be compiled and linked to with the + libsystemd pkg-config1 file. + + + + Examples + + Use the SD_JOURNAL_FOREACH_FIELD macro to iterate through all field names in use in the + current journal. + + #include <stdio.h> +#include <string.h> +#include <systemd/sd-journal.h> + +int main(int argc, char *argv[]) { + sd_journal *j; + const char *field; + int r; + + r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY); + if (r < 0) { + fprintf(stderr, "Failed to open journal: %s\n", strerror(-r)); + return 1; + } + SD_JOURNAL_FOREACH_FIELD(j, field) + printf("%s\n", field); + sd_journal_close(j); + return 0; +} + + + + + See Also + + + systemd1, + systemd.journal-fields7, + sd-journal3, + sd_journal_open3, + sd_journal_query_unique3, + sd_journal_get_data3, + sd_journal_add_match3 + + + + diff --git a/man/sd_journal_query_unique.xml b/man/sd_journal_query_unique.xml index ac0e5f633f..dbff55c105 100644 --- a/man/sd_journal_query_unique.xml +++ b/man/sd_journal_query_unique.xml @@ -128,6 +128,11 @@ Note that these functions currently are not influenced by matches set with sd_journal_add_match() but this might change in a later version of this software. + + To enumerate all field names currently in use (and thus all suitable field parameters for + sd_journal_query_unique()), use the + sd_journal_enumerate_fields3 + call. @@ -167,25 +172,25 @@ #include <systemd/sd-journal.h> int main(int argc, char *argv[]) { - sd_journal *j; - const void *d; - size_t l; - int r; - - r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY); - if (r < 0) { - fprintf(stderr, "Failed to open journal: %s\n", strerror(-r)); - return 1; - } - r = sd_journal_query_unique(j, "_SYSTEMD_UNIT"); - if (r < 0) { - fprintf(stderr, "Failed to query journal: %s\n", strerror(-r)); - return 1; - } - SD_JOURNAL_FOREACH_UNIQUE(j, d, l) - printf("%.*s\n", (int) l, (const char*) d); - sd_journal_close(j); - return 0; + sd_journal *j; + const void *d; + size_t l; + int r; + + r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY); + if (r < 0) { + fprintf(stderr, "Failed to open journal: %s\n", strerror(-r)); + return 1; + } + r = sd_journal_query_unique(j, "_SYSTEMD_UNIT"); + if (r < 0) { + fprintf(stderr, "Failed to query journal: %s\n", strerror(-r)); + return 1; + } + SD_JOURNAL_FOREACH_UNIQUE(j, d, l) + printf("%.*s\n", (int) l, (const char*) d); + sd_journal_close(j); + return 0; } @@ -198,6 +203,7 @@ int main(int argc, char *argv[]) { systemd.journal-fields7, sd-journal3, sd_journal_open3, + sd_journal_enumerate_fields3, sd_journal_get_data3, sd_journal_add_match3 -- cgit v1.2.3-54-g00ecf From 69e714f3d8784fb0207ac9112ed1a48d4fd5e9fe Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 27 Jan 2016 19:01:42 +0100 Subject: journalctl: add new --fields switch to dump all currently used field names Fixes #2176 --- man/journalctl.xml | 7 +++++++ src/journal/journalctl.c | 30 ++++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) (limited to 'man') diff --git a/man/journalctl.xml b/man/journalctl.xml index b57afb6ebf..5af98c67cb 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -571,6 +571,13 @@ field can take in all entries of the journal. + + + + + Print all field names currently used in all entries of the journal. + + diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 1686f38c4e..cda24c4d18 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -136,6 +136,8 @@ static enum { ACTION_SYNC, ACTION_ROTATE, ACTION_VACUUM, + ACTION_LIST_FIELDS, + ACTION_LIST_FIELD_NAMES, } arg_action = ACTION_SHOW; typedef struct BootId { @@ -244,6 +246,7 @@ static void help(void) { "\nCommands:\n" " -h --help Show this help text\n" " --version Show package version\n" + " -N --fields List all field names currently used\n" " -F --field=FIELD List all values that a specified field takes\n" " --disk-usage Show total disk usage of all journal files\n" " --vacuum-size=BYTES Reduce disk usage below specified size\n" @@ -340,6 +343,7 @@ static int parse_argv(int argc, char *argv[]) { { "unit", required_argument, NULL, 'u' }, { "user-unit", required_argument, NULL, ARG_USER_UNIT }, { "field", required_argument, NULL, 'F' }, + { "fields", no_argument, NULL, 'N' }, { "catalog", no_argument, NULL, 'x' }, { "list-catalog", no_argument, NULL, ARG_LIST_CATALOG }, { "dump-catalog", no_argument, NULL, ARG_DUMP_CATALOG }, @@ -361,7 +365,7 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "hefo:aln::qmb::kD:p:c:S:U:t:u:F:xrM:", options, NULL)) >= 0) + while ((c = getopt_long(argc, argv, "hefo:aln::qmb::kD:p:c:S:U:t:u:NF:xrM:", options, NULL)) >= 0) switch (c) { @@ -698,9 +702,14 @@ static int parse_argv(int argc, char *argv[]) { break; case 'F': + arg_action = ACTION_LIST_FIELDS; arg_field = optarg; break; + case 'N': + arg_action = ACTION_LIST_FIELD_NAMES; + break; + case 'x': arg_catalog = true; break; @@ -2003,6 +2012,8 @@ int main(int argc, char *argv[]) { case ACTION_DISK_USAGE: case ACTION_LIST_BOOTS: case ACTION_VACUUM: + case ACTION_LIST_FIELDS: + case ACTION_LIST_FIELD_NAMES: /* These ones require access to the journal files, continue below. */ break; @@ -2085,7 +2096,20 @@ int main(int argc, char *argv[]) { goto finish; } + case ACTION_LIST_FIELD_NAMES: { + const char *field; + + SD_JOURNAL_FOREACH_FIELD(j, field) { + printf("%s\n", field); + n_shown ++; + } + + r = 0; + goto finish; + } + case ACTION_SHOW: + case ACTION_LIST_FIELDS: break; default: @@ -2139,10 +2163,12 @@ int main(int argc, char *argv[]) { log_debug("Journal filter: %s", filter); } - if (arg_field) { + if (arg_action == ACTION_LIST_FIELDS) { const void *data; size_t size; + assert(arg_field); + r = sd_journal_set_data_threshold(j, 0); if (r < 0) { log_error_errno(r, "Failed to unset data size threshold: %m"); -- cgit v1.2.3-54-g00ecf