X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Flogs-show.c;h=8897a10c2b427750742667a06247629c3bb8bce5;hp=ca5ad43b633477fc8d76379f84a1a2e572c1bebb;hb=e86b80b834016d273196c5ec9687fddcddcf9381;hpb=93b73b064c663d6248bebfbbbd82989b5ca10fc5 diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index ca5ad43b6..8897a10c2 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -179,6 +179,9 @@ static int output_short( if (!message) return 0; + if (!(flags & OUTPUT_SHOW_ALL)) + strip_tab_ansi(&message, &message_len); + if (priority_len == 1 && *priority >= '0' && *priority <= '7') p = *priority - '0'; @@ -274,7 +277,7 @@ static int output_short( } else if ((flags & OUTPUT_FULL_WIDTH) || (message_len + n + 1 < n_columns)) fprintf(f, ": %s%.*s%s\n", color_on, (int) message_len, message, color_off); else if (n < n_columns && n_columns - n - 2 >= 3) { - char *e; + char _cleanup_free_ *e; e = ellipsize_mem(message, message_len, n_columns - n - 2, 90); @@ -282,8 +285,6 @@ static int output_short( fprintf(f, ": %s%.*s%s\n", color_on, (int) message_len, message, color_off); else fprintf(f, ": %s%s%s\n", color_on, e, color_off); - - free(e); } else fputs("\n", f); @@ -302,7 +303,7 @@ static int output_verbose( const void *data; size_t length; - char *cursor; + char _cleanup_free_ *cursor = NULL; uint64_t realtime; char ts[FORMAT_TIMESTAMP_MAX]; int r; @@ -328,8 +329,6 @@ static int output_verbose( format_timestamp(ts, sizeof(ts), realtime), cursor); - free(cursor); - SD_JOURNAL_FOREACH_DATA(j, data, length) { if (!shall_print(data, length, flags)) { const char *c; @@ -366,7 +365,7 @@ static int output_export( char sid[33]; int r; usec_t realtime, monotonic; - char *cursor; + char _cleanup_free_ *cursor = NULL; const void *data; size_t length; @@ -402,8 +401,6 @@ static int output_export( (unsigned long long) monotonic, sd_id128_to_string(boot_id, sid)); - free(cursor); - SD_JOURNAL_FOREACH_DATA(j, data, length) { /* We already printed the boot id, from the data in @@ -497,11 +494,11 @@ static int output_json( OutputFlags flags) { uint64_t realtime, monotonic; - char *cursor, *k; + char _cleanup_free_ *cursor = NULL; const void *data; size_t length; sd_id128_t boot_id; - char sid[33]; + char sid[33], *k; int r; Hashmap *h = NULL; bool done, separator; @@ -553,7 +550,6 @@ static int output_json( (unsigned long long) monotonic, sd_id128_to_string(boot_id, sid)); } - free(cursor); h = hashmap_new(string_hash_func, string_compare_func); if (!h) @@ -778,72 +774,22 @@ int output_journal( return ret; } -int show_journal_by_unit( - FILE *f, - const char *unit, - OutputMode mode, - unsigned n_columns, - usec_t not_before, - unsigned how_many, - OutputFlags flags) { +static int show_journal(FILE *f, + sd_journal *j, + OutputMode mode, + unsigned n_columns, + usec_t not_before, + unsigned how_many, + OutputFlags flags) { - _cleanup_free_ 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(j); assert(mode >= 0); assert(mode < _OUTPUT_MODE_MAX); - assert(unit); - - if (!endswith(unit, ".service") && - !endswith(unit, ".socket") && - !endswith(unit, ".mount") && - !endswith(unit, ".swap")) - return 0; - - if (how_many <= 0) - return 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; - } - - r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY|SD_JOURNAL_SYSTEM_ONLY); - if (r < 0) - goto finish; - - /* 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); @@ -920,12 +866,110 @@ int show_journal_by_unit( } finish: - if (j) - sd_journal_close(j); + return r; +} + +int add_matches_for_unit(sd_journal *j, const char *unit) { + int r; + _cleanup_free_ char *m1 = NULL, *m2 = NULL, *m3 = NULL; + assert(j); + assert(unit); + + if (asprintf(&m1, "_SYSTEMD_UNIT=%s", unit) < 0 || + asprintf(&m2, "COREDUMP_UNIT=%s", unit) < 0 || + asprintf(&m3, "UNIT=%s", unit) < 0) + return -ENOMEM; + + (void)( + /* Look for messages from the service itself */ + (r = sd_journal_add_match(j, m1, 0)) || + + /* Look for coredumps of the service */ + (r = sd_journal_add_disjunction(j)) || + (r = sd_journal_add_match(j, + "MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1", 0)) || + (r = sd_journal_add_match(j, m2, 0)) || + + /* Look for messages from PID 1 about this service */ + (r = sd_journal_add_disjunction(j)) || + (r = sd_journal_add_match(j, "_PID=1", 0)) || + (r = sd_journal_add_match(j, m3, 0)) + ); return r; } +int add_matches_for_user_unit(sd_journal *j, const char *unit, uid_t uid) { + int r; + _cleanup_free_ char *m1 = NULL, *m2 = NULL, *m3 = NULL, *m4 = NULL; + + assert(j); + assert(unit); + + if (asprintf(&m1, "_SYSTEMD_USER_UNIT=%s", unit) < 0 || + asprintf(&m2, "USER_UNIT=%s", unit) < 0 || + asprintf(&m3, "COREDUMP_USER_UNIT=%s", unit) < 0 || + asprintf(&m4, "_UID=%d", uid) < 0) + return -ENOMEM; + + (void) ( + /* Look for messages from the user service itself */ + (r = sd_journal_add_match(j, m1, 0)) || + (r = sd_journal_add_match(j, m4, 0)) || + + /* Look for messages from systemd about this service */ + (r = sd_journal_add_disjunction(j)) || + (r = sd_journal_add_match(j, m2, 0)) || + (r = sd_journal_add_match(j, m4, 0)) || + + /* Look for coredumps of the service */ + (r = sd_journal_add_disjunction(j)) || + (r = sd_journal_add_match(j, m3, 0)) || + (r = sd_journal_add_match(j, m4, 0)) + ); + return r; +} + +int show_journal_by_unit( + FILE *f, + const char *unit, + OutputMode mode, + unsigned n_columns, + usec_t not_before, + unsigned how_many, + uid_t uid, + OutputFlags flags, + bool system) { + + sd_journal _cleanup_journal_close_ *j = NULL; + int r; + int jflags = SD_JOURNAL_LOCAL_ONLY | system * SD_JOURNAL_SYSTEM_ONLY; + + assert(mode >= 0); + assert(mode < _OUTPUT_MODE_MAX); + assert(unit); + + if (how_many <= 0) + return 0; + + r = sd_journal_open(&j, jflags); + if (r < 0) + return r; + + if (system) + r = add_matches_for_unit(j, unit); + else + r = add_matches_for_user_unit(j, unit, uid); + if (r < 0) + return r; + + r = show_journal(f, j, mode, n_columns, not_before, how_many, flags); + if (r < 0) + return r; + + return 0; +} + static const char *const output_mode_table[_OUTPUT_MODE_MAX] = { [OUTPUT_SHORT] = "short", [OUTPUT_SHORT_MONOTONIC] = "short-monotonic",