From: Zbigniew Jędrzejewski-Szmek Date: Wed, 20 Mar 2013 00:54:04 +0000 (-0400) Subject: journalct: beef up entry listing X-Git-Tag: v199~148 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=54b7254c1fa629937f92fd6fa34bdf127b696a00 journalct: beef up entry listing The ability to dump catalog entries in full and by id is added. --- diff --git a/man/journalctl.xml b/man/journalctl.xml index 8883da278..6b4b7572f 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -49,7 +49,9 @@ - journalctl OPTIONS MATCHES + journalctl + OPTIONS + MATCHES @@ -479,12 +481,39 @@ - + List the contents of the message catalog, as table of message IDs plus their short - description strings. + description strings. + + If any + ID128s are + specified, only those entries are shown. + + + + + + + + Show the contents of + the message catalog, with entries + separated by a line consisting of two + dashes and the id (the format is the + same as .catalog + files. + + If any + ID128s are + specified, only those entries are shown. + + diff --git a/src/journal/catalog.c b/src/journal/catalog.c index 32256f626..dacf5c50a 100644 --- a/src/journal/catalog.c +++ b/src/journal/catalog.c @@ -551,7 +551,23 @@ static char *find_header(const char *s, const char *header) { } } -int catalog_list(FILE *f) { +static void dump_catalog_entry(FILE *f, sd_id128_t id, const char *s, bool oneline) { + if (oneline) { + _cleanup_free_ char *subject = NULL, *defined_by = NULL; + + subject = find_header(s, "Subject:"); + defined_by = find_header(s, "Defined-By:"); + + fprintf(f, SD_ID128_FORMAT_STR " %s: %s\n", + SD_ID128_FORMAT_VAL(id), + strna(defined_by), strna(subject)); + } else + fprintf(f, "-- " SD_ID128_FORMAT_STR "\n%s\n", + SD_ID128_FORMAT_VAL(id), s); +} + + +int catalog_list(FILE *f, bool oneline) { _cleanup_close_ int fd = -1; void *p = NULL; struct stat st; @@ -571,17 +587,13 @@ int catalog_list(FILE *f) { for (n = 0; n < le64toh(h->n_items); n++) { const char *s; - _cleanup_free_ char *subject = NULL, *defined_by = NULL; if (last_id_set && sd_id128_equal(last_id, items[n].id)) continue; assert_se(s = find_id(p, items[n].id)); - subject = find_header(s, "Subject:"); - defined_by = find_header(s, "Defined-By:"); - - fprintf(f, SD_ID128_FORMAT_STR " %s: %s\n", SD_ID128_FORMAT_VAL(items[n].id), strna(defined_by), strna(subject)); + dump_catalog_entry(f, items[n].id, s, oneline); last_id_set = true; last_id = items[n].id; @@ -591,3 +603,37 @@ int catalog_list(FILE *f) { return 0; } + +int catalog_list_items(FILE *f, bool oneline, char **items) { + char **item; + int r = 0; + + STRV_FOREACH(item, items) { + sd_id128_t id; + int k; + char _cleanup_free_ *msg = NULL; + + k = sd_id128_from_string(*item, &id); + if (k < 0) { + log_error("Failed to parse id128 '%s': %s", + *item, strerror(-r)); + if (r < 0) + r = k; + continue; + } + + k = catalog_get(id, &msg); + if (k < 0) { + log_full(k == -ENOENT ? LOG_NOTICE : LOG_ERR, + "Failed to retrieve catalog entry for '%s': %s", + *item, strerror(-r)); + if (r < 0) + r = k; + continue; + } + + dump_catalog_entry(f, id, msg, oneline); + } + + return r; +} diff --git a/src/journal/catalog.h b/src/journal/catalog.h index 9add773c9..8ea2c41c2 100644 --- a/src/journal/catalog.h +++ b/src/journal/catalog.h @@ -21,8 +21,11 @@ along with systemd; If not, see . ***/ +#include + #include "sd-id128.h" int catalog_update(void); int catalog_get(sd_id128_t id, char **data); -int catalog_list(FILE *f); +int catalog_list(FILE *f, bool oneline); +int catalog_list_items(FILE *f, bool oneline, char **items); diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 8aef923be..975c44fa9 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -90,6 +90,7 @@ static enum { ACTION_VERIFY, ACTION_DISK_USAGE, ACTION_LIST_CATALOG, + ACTION_DUMP_CATALOG, ACTION_UPDATE_CATALOG } arg_action = ACTION_SHOW; @@ -131,6 +132,7 @@ static int help(void) { " --disk-usage Show total disk usage\n" " -F --field=FIELD List all values a certain field takes\n" " --list-catalog Show message IDs of all entries in the message catalog\n" + " --dump-catalog Show entries in the message catalog\n" " --update-catalog Update the message catalog database\n" #ifdef HAVE_GCRYPT " --setup-keys Generate new FSS key pair\n" @@ -159,6 +161,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_UNTIL, ARG_USER_UNIT, ARG_LIST_CATALOG, + ARG_DUMP_CATALOG, ARG_UPDATE_CATALOG }; @@ -193,6 +196,7 @@ static int parse_argv(int argc, char *argv[]) { { "field", required_argument, NULL, 'F' }, { "catalog", no_argument, NULL, 'x' }, { "list-catalog", no_argument, NULL, ARG_LIST_CATALOG }, + { "dump-catalog", no_argument, NULL, ARG_DUMP_CATALOG }, { "update-catalog",no_argument, NULL, ARG_UPDATE_CATALOG }, { "reverse", no_argument, NULL, 'r' }, { NULL, 0, NULL, 0 } @@ -445,6 +449,10 @@ static int parse_argv(int argc, char *argv[]) { arg_action = ACTION_LIST_CATALOG; break; + case ARG_DUMP_CATALOG: + arg_action = ACTION_DUMP_CATALOG; + break; + case ARG_UPDATE_CATALOG: arg_action = ACTION_UPDATE_CATALOG; break; @@ -918,8 +926,13 @@ int main(int argc, char *argv[]) { goto finish; } - if (arg_action == ACTION_LIST_CATALOG) { - r = catalog_list(stdout); + if (arg_action == ACTION_LIST_CATALOG || + arg_action == ACTION_DUMP_CATALOG) { + bool oneline = arg_action == ACTION_LIST_CATALOG; + if (optind < argc) + r = catalog_list_items(stdout, oneline, argv + optind); + else + r = catalog_list(stdout, oneline); if (r < 0) log_error("Failed to list catalog: %s", strerror(-r)); goto finish; diff --git a/src/journal/test-catalog.c b/src/journal/test-catalog.c index cec8a11c4..c75b1464f 100644 --- a/src/journal/test-catalog.c +++ b/src/journal/test-catalog.c @@ -36,7 +36,9 @@ int main(int argc, char *argv[]) { assert_se(catalog_update() >= 0); - assert_se(catalog_list(stdout) >= 0); + assert_se(catalog_list(stdout, true) >= 0); + + assert_se(catalog_list(stdout, false) >= 0); assert_se(catalog_get(SD_MESSAGE_COREDUMP, &text) >= 0);