X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Flogs-show.c;h=99407c9c1d550bcee2712fe65e0d6cb9df9cb703;hp=426a9d617cf2678117ac7efafc781b6080ed81e5;hb=1946b0bd55b356ea25bd747cb338a4b31fabeecf;hpb=b59866aefa110d368460edc14f98cd6d79fe05cd diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index 426a9d617..99407c9c1 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -50,12 +50,11 @@ static int parse_field(const void *data, size_t length, const char *field, char nl = length - fl; buf = malloc(nl+1); + if (!buf) + return log_oom(); + memcpy(buf, (const char*) data + fl, nl); ((char*)buf)[nl] = 0; - if (!buf) { - log_error("Out of memory"); - return -ENOMEM; - } free(*target); *target = buf; @@ -77,18 +76,27 @@ static bool shall_print(bool show_all, char *p, size_t l) { return true; } -static int output_short(sd_journal *j, unsigned line, unsigned n_columns, bool show_all, bool monotonic_mode) { +static int output_short(sd_journal *j, unsigned line, unsigned n_columns, + OutputFlags flags) { int r; const void *data; size_t length; size_t n = 0; - char *hostname = NULL, *identifier = NULL, *comm = NULL, *pid = NULL, *fake_pid = NULL, *message = NULL, *realtime = NULL, *monotonic = NULL; - size_t hostname_len = 0, identifier_len = 0, comm_len = 0, pid_len = 0, fake_pid_len = 0, message_len = 0, realtime_len = 0, monotonic_len = 0; + char *hostname = NULL, *identifier = NULL, *comm = NULL, *pid = NULL, *fake_pid = NULL, *message = NULL, *realtime = NULL, *monotonic = NULL, *priority = NULL; + size_t hostname_len = 0, identifier_len = 0, comm_len = 0, pid_len = 0, fake_pid_len = 0, message_len = 0, realtime_len = 0, monotonic_len = 0, priority_len = 0; + int p = LOG_INFO; + const char *color_on = "", *color_off = ""; assert(j); SD_JOURNAL_FOREACH_DATA(j, data, length) { + r = parse_field(data, length, "PRIORITY=", &priority, &priority_len); + if (r < 0) + goto finish; + else if (r > 0) + continue; + r = parse_field(data, length, "_HOSTNAME=", &hostname, &hostname_len); if (r < 0) goto finish; @@ -141,7 +149,10 @@ static int output_short(sd_journal *j, unsigned line, unsigned n_columns, bool s goto finish; } - if (monotonic_mode) { + if (priority_len == 1 && *priority >= '0' && *priority <= '7') + p = *priority - '0'; + + if (flags & OUTPUT_MONOTONIC_MODE) { uint64_t t; sd_id128_t boot_id; @@ -193,44 +204,59 @@ static int output_short(sd_journal *j, unsigned line, unsigned n_columns, bool s n += strlen(buf); } - if (hostname && shall_print(show_all, hostname, hostname_len)) { + if (hostname && shall_print(flags & OUTPUT_SHOW_ALL, + hostname, hostname_len)) { printf(" %.*s", (int) hostname_len, hostname); n += hostname_len + 1; } - if (identifier && shall_print(show_all, identifier, identifier_len)) { + if (identifier && shall_print(flags & OUTPUT_SHOW_ALL, + identifier, identifier_len)) { printf(" %.*s", (int) identifier_len, identifier); n += identifier_len + 1; - } else if (comm && shall_print(show_all, comm, comm_len)) { + } else if (comm && shall_print(flags & OUTPUT_SHOW_ALL, + comm, comm_len)) { printf(" %.*s", (int) comm_len, comm); n += comm_len + 1; } else putchar(' '); - if (pid && shall_print(show_all, pid, pid_len)) { + if (pid && shall_print(flags & OUTPUT_SHOW_ALL, pid, pid_len)) { printf("[%.*s]", (int) pid_len, pid); n += pid_len + 2; - } else if (fake_pid && shall_print(show_all, fake_pid, fake_pid_len)) { + } else if (fake_pid && shall_print(flags & OUTPUT_SHOW_ALL, + fake_pid, fake_pid_len)) { printf("[%.*s]", (int) fake_pid_len, fake_pid); n += fake_pid_len + 2; } - if (show_all) - printf(": %.*s\n", (int) message_len, message); + if (flags & OUTPUT_COLOR) { + if (p <= LOG_ERR) { + color_on = ANSI_HIGHLIGHT_RED_ON; + color_off = ANSI_HIGHLIGHT_OFF; + } else if (p <= LOG_NOTICE) { + color_on = ANSI_HIGHLIGHT_ON; + color_off = ANSI_HIGHLIGHT_OFF; + } + } + + if (flags & OUTPUT_SHOW_ALL) + printf(": %s%.*s%s\n", color_on, (int) message_len, message, color_off); else if (!utf8_is_printable_n(message, message_len)) { char bytes[FORMAT_BYTES_MAX]; printf(": [%s blob data]\n", format_bytes(bytes, sizeof(bytes), message_len)); - } else if (message_len + n < n_columns) - printf(": %.*s\n", (int) message_len, message); - else if (n < n_columns) { + } else if ((flags & OUTPUT_FULL_WIDTH) || + (message_len + n + 1 < n_columns)) + printf(": %s%.*s%s\n", color_on, (int) message_len, message, color_off); + else if (n < n_columns && n_columns - n - 2 >= 3) { char *e; e = ellipsize_mem(message, message_len, n_columns - n - 2, 90); if (!e) - printf(": %.*s\n", (int) message_len, message); + printf(": %s%.*s%s\n", color_on, (int) message_len, message, color_off); else - printf(": %s\n", e); + printf(": %s%s%s\n", color_on, e, color_off); free(e); } else @@ -247,19 +273,23 @@ finish: free(message); free(monotonic); free(realtime); + free(priority); return r; } -static int output_short_realtime(sd_journal *j, unsigned line, unsigned n_columns, bool show_all) { - return output_short(j, line, n_columns, show_all, false); +static int output_short_realtime(sd_journal *j, unsigned line, + unsigned n_columns, OutputFlags flags) { + return output_short(j, line, n_columns, flags & ~OUTPUT_MONOTONIC_MODE); } -static int output_short_monotonic(sd_journal *j, unsigned line, unsigned n_columns, bool show_all) { - return output_short(j, line, n_columns, show_all, true); +static int output_short_monotonic(sd_journal *j, unsigned line, + unsigned n_columns, OutputFlags flags) { + return output_short(j, line, n_columns, flags | OUTPUT_MONOTONIC_MODE); } -static int output_verbose(sd_journal *j, unsigned line, unsigned n_columns, bool show_all) { +static int output_verbose(sd_journal *j, unsigned line, + unsigned n_columns, OutputFlags flags) { const void *data; size_t length; char *cursor; @@ -288,7 +318,7 @@ static int output_verbose(sd_journal *j, unsigned line, unsigned n_columns, bool free(cursor); SD_JOURNAL_FOREACH_DATA(j, data, length) { - if (!show_all && (length > PRINT_THRESHOLD || + if (!(flags & OUTPUT_SHOW_ALL) && (length > PRINT_THRESHOLD || !utf8_is_printable_n(data, length))) { const char *c; char bytes[FORMAT_BYTES_MAX]; @@ -310,7 +340,8 @@ static int output_verbose(sd_journal *j, unsigned line, unsigned n_columns, bool return 0; } -static int output_export(sd_journal *j, unsigned line, unsigned n_columns, bool show_all) { +static int output_export(sd_journal *j, unsigned line, + unsigned n_columns, OutputFlags flags) { sd_id128_t boot_id; char sid[33]; int r; @@ -421,7 +452,8 @@ static void json_escape(const char* p, size_t l) { } } -static int output_json(sd_journal *j, unsigned line, unsigned n_columns, bool show_all) { +static int output_json(sd_journal *j, unsigned line, + unsigned n_columns, OutputFlags flags) { uint64_t realtime, monotonic; char *cursor; const void *data; @@ -494,7 +526,8 @@ static int output_json(sd_journal *j, unsigned line, unsigned n_columns, bool sh return 0; } -static int output_cat(sd_journal *j, unsigned line, unsigned n_columns, bool show_all) { +static int output_cat(sd_journal *j, unsigned line, + unsigned n_columns, OutputFlags flags) { const void *data; size_t l; int r; @@ -515,7 +548,8 @@ static int output_cat(sd_journal *j, unsigned line, unsigned n_columns, bool sho return 0; } -static int (*output_funcs[_OUTPUT_MODE_MAX])(sd_journal*j, unsigned line, unsigned n_columns, bool show_all) = { +static int (*output_funcs[_OUTPUT_MODE_MAX])(sd_journal*j, unsigned line, + unsigned n_columns, OutputFlags flags) = { [OUTPUT_SHORT] = output_short_realtime, [OUTPUT_SHORT_MONOTONIC] = output_short_monotonic, [OUTPUT_VERBOSE] = output_verbose, @@ -524,14 +558,15 @@ static int (*output_funcs[_OUTPUT_MODE_MAX])(sd_journal*j, unsigned line, unsign [OUTPUT_CAT] = output_cat }; -int output_journal(sd_journal *j, OutputMode mode, unsigned line, unsigned n_columns, bool show_all) { +int output_journal(sd_journal *j, OutputMode mode, unsigned line, + unsigned n_columns, OutputFlags flags) { assert(mode >= 0); assert(mode < _OUTPUT_MODE_MAX); if (n_columns <= 0) n_columns = columns(); - return output_funcs[mode](j, line, n_columns, show_all); + return output_funcs[mode](j, line, n_columns, flags); } int show_journal_by_unit( @@ -540,15 +575,14 @@ int show_journal_by_unit( unsigned n_columns, usec_t not_before, unsigned how_many, - bool show_all, - bool follow, - bool warn_cutoff) { + OutputFlags flags) { - char *m = NULL; + char *m1 = NULL, *m2 = NULL, *m3 = NULL; sd_journal *j = NULL; int r; unsigned line = 0; bool need_seek = false; + int warn_cutoff = flags & OUTPUT_WARN_CUTOFF; assert(mode >= 0); assert(mode < _OUTPUT_MODE_MAX); @@ -563,7 +597,9 @@ int show_journal_by_unit( if (how_many <= 0) return 0; - if (asprintf(&m, "_SYSTEMD_UNIT=%s", unit) < 0) { + if (asprintf(&m1, "_SYSTEMD_UNIT=%s", unit) < 0 || + asprintf(&m2, "COREDUMP_UNIT=%s", unit) < 0 || + asprintf(&m3, "UNIT=%s", unit) < 0) { r = -ENOMEM; goto finish; } @@ -572,10 +608,34 @@ int show_journal_by_unit( if (r < 0) goto finish; - r = sd_journal_add_match(j, m, strlen(m)); + /* Look for messages from the service itself */ + r = sd_journal_add_match(j, m1, 0); + if (r < 0) + goto finish; + + /* Look for coredumps of the service */ + r = sd_journal_add_disjunction(j); + if (r < 0) + goto finish; + r = sd_journal_add_match(j, "MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1", 0); + if (r < 0) + goto finish; + r = sd_journal_add_match(j, m2, 0); + if (r < 0) + goto finish; + + /* Look for messages from PID 1 about this service */ + r = sd_journal_add_disjunction(j); + if (r < 0) + goto finish; + r = sd_journal_add_match(j, "_PID=1", 0); + if (r < 0) + goto finish; + r = sd_journal_add_match(j, m3, 0); if (r < 0) goto finish; + /* Seek to end */ r = sd_journal_seek_tail(j); if (r < 0) goto finish; @@ -620,7 +680,7 @@ int show_journal_by_unit( line ++; - r = output_journal(j, mode, line, n_columns, show_all); + r = output_journal(j, mode, line, n_columns, flags); if (r < 0) goto finish; } @@ -645,7 +705,7 @@ int show_journal_by_unit( warn_cutoff = false; } - if (!follow) + if (!(flags & OUTPUT_FOLLOW)) break; r = sd_journal_wait(j, (usec_t) -1); @@ -658,8 +718,9 @@ int show_journal_by_unit( fputs("\n]\n", stdout); finish: - if (m) - free(m); + free(m1); + free(m2); + free(m3); if (j) sd_journal_close(j);