X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flogs-show.c;h=539dfeddb63a95ab0aa1a6d7df7857dd5634663c;hb=ea41a8a973a7b9f628d93fa501131dfc2f6cc024;hp=d178f95f94a6c34a70c7c3b47d9798abdb99c690;hpb=86aa7ba4f9969bbfc75ebd51f944313695f1a0a1;p=elogind.git diff --git a/src/logs-show.c b/src/logs-show.c index d178f95f9..539dfeddb 100644 --- a/src/logs-show.c +++ b/src/logs-show.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "logs-show.h" #include "log.h" @@ -328,38 +329,50 @@ static int (*output_funcs[_OUTPUT_MODE_MAX])(sd_journal*j, unsigned line, bool s [OUTPUT_JSON] = output_json }; -int output_journal(sd_journal *j, output_mode mode, unsigned line, bool show_all) { +int output_journal(sd_journal *j, OutputMode mode, unsigned line, bool show_all) { + assert(mode >= 0); assert(mode < _OUTPUT_MODE_MAX); return output_funcs[mode](j, line, show_all); } -int show_journal_by_service( - const char *service, - output_mode mode, +int show_journal_by_unit( + const char *unit, + OutputMode mode, const char *prefix, unsigned n_columns, usec_t not_before, unsigned how_many, - bool show_all) { + bool show_all, + bool follow) { char *m = NULL; sd_journal *j; int r; - unsigned i; + int fd; + unsigned line = 0; + bool need_seek = false; - assert(service); + assert(mode >= 0); + assert(mode < _OUTPUT_MODE_MAX); + assert(unit); - if (n_columns <= 0) - n_columns = columns(); + if (!endswith(unit, ".service") && + !endswith(unit, ".socket") && + !endswith(unit, ".mount") && + !endswith(unit, ".swap")) + return 0; if (how_many <= 0) - how_many = 10; + return 0; + + if (n_columns <= 0) + n_columns = columns(); if (!prefix) prefix = ""; - if (asprintf(&m, "_SYSTEMD_SERVICE=%s", service) < 0) { + if (asprintf(&m, "_SYSTEMD_UNIT=%s", unit) < 0) { r = -ENOMEM; goto finish; } @@ -368,6 +381,10 @@ int show_journal_by_service( if (r < 0) goto finish; + fd = sd_journal_get_fd(j); + if (fd < 0) + goto finish; + r = sd_journal_add_match(j, m, strlen(m)); if (r < 0) goto finish; @@ -376,23 +393,67 @@ int show_journal_by_service( if (r < 0) goto finish; - for (i = 0; i < how_many; i++) - sd_journal_previous(j); + r = sd_journal_previous_skip(j, how_many); + if (r < 0) + goto finish; - for (i = 0; i < how_many; i++) { + if (mode == OUTPUT_JSON) { + fputc('[', stdout); + fflush(stdout); + } - r = sd_journal_next(j); - if (r < 0) - goto finish; + for (;;) { + for (;;) { + usec_t usec; + + if (need_seek) { + r = sd_journal_next(j); + if (r < 0) + goto finish; + } + + if (r == 0) + break; - if (r == 0) + need_seek = true; + + if (not_before > 0) { + r = sd_journal_get_monotonic_usec(j, &usec, NULL); + + /* -ESTALE is returned if the + timestamp is not from this boot */ + if (r == -ESTALE) + continue; + else if (r < 0) + goto finish; + + if (usec < not_before) + continue; + } + + line ++; + + r = output_journal(j, mode, line, show_all); + if (r < 0) + goto finish; + } + + if (!follow) break; - r = output_journal(j, mode, i+1, show_all); + r = fd_wait_for_event(fd, POLLIN); if (r < 0) goto finish; + + r = sd_journal_process(j); + if (r < 0) + goto finish; + } + if (mode == OUTPUT_JSON) + fputs("\n]\n", stdout); + finish: if (m) free(m); @@ -402,3 +463,12 @@ finish: return r; } + +static const char *const output_mode_table[_OUTPUT_MODE_MAX] = { + [OUTPUT_SHORT] = "short", + [OUTPUT_VERBOSE] = "verbose", + [OUTPUT_EXPORT] = "export", + [OUTPUT_JSON] = "json" +}; + +DEFINE_STRING_TABLE_LOOKUP(output_mode, OutputMode);