X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fshared%2Flogs-show.c;h=8dc11bb7fd983cf98984d1c14402a526340c699f;hb=d7bd3de0654669e65b9642c248c5fa6d1d9a9f61;hp=b88547eb83a47c6968cd92efd9e8204042242fc4;hpb=31f7bf1994523f5b8fd014c69b97e09d7043d9ff;p=elogind.git diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index b88547eb8..8dc11bb7f 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -101,7 +101,7 @@ static bool shall_print(const char *p, size_t l, OutputFlags flags) { return true; } -static void print_multiline(FILE *f, unsigned prefix, unsigned n_columns, int flags, int priority, const char* message, size_t message_len) { +static void print_multiline(FILE *f, unsigned prefix, unsigned n_columns, OutputMode flags, int priority, const char* message, size_t message_len) { const char *color_on = "", *color_off = ""; const char *pos, *end; bool continuation = false; @@ -123,7 +123,7 @@ static void print_multiline(FILE *f, unsigned prefix, unsigned n_columns, int fl len = end - pos; assert(len >= 0); - if ((flags & OUTPUT_FULL_WIDTH) || (prefix + len + 1 < n_columns)) + if (flags & (OUTPUT_FULL_WIDTH | OUTPUT_SHOW_ALL) || prefix + len + 1 < n_columns) fprintf(f, "%*s%s%.*s%s\n", continuation * prefix, "", color_on, len, pos, color_off); @@ -163,7 +163,7 @@ static int output_short( sd_journal_set_data_threshold(j, flags & OUTPUT_SHOW_ALL ? 0 : PRINT_THRESHOLD); - SD_JOURNAL_FOREACH_DATA(j, data, length) { + JOURNAL_FOREACH_DATA_RETVAL(j, data, length, r) { r = parse_field(data, length, "PRIORITY=", &priority, &priority_len); if (r < 0) @@ -218,6 +218,9 @@ static int output_short( return r; } + if (r < 0) + return r; + if (!message) return 0; @@ -240,7 +243,7 @@ static int output_short( r = sd_journal_get_monotonic_usec(j, &t, &boot_id); if (r < 0) { - log_error("Failed to get monotonic: %s", strerror(-r)); + log_error("Failed to get monotonic timestamp: %s", strerror(-r)); return r; } @@ -265,7 +268,7 @@ static int output_short( r = sd_journal_get_realtime_usec(j, &x); if (r < 0) { - log_error("Failed to get realtime: %s", strerror(-r)); + log_error("Failed to get realtime timestamp: %s", strerror(-r)); return r; } @@ -336,7 +339,8 @@ static int output_verbose( r = sd_journal_get_realtime_usec(j, &realtime); if (r < 0) { - log_error("Failed to get realtime timestamp: %s", strerror(-r)); + log_full(r == -EADDRNOTAVAIL ? LOG_DEBUG : LOG_ERR, + "Failed to get realtime timestamp: %s", strerror(-r)); return r; } @@ -350,9 +354,11 @@ static int output_verbose( format_timestamp(ts, sizeof(ts), realtime), cursor); - SD_JOURNAL_FOREACH_DATA(j, data, length) { + JOURNAL_FOREACH_DATA_RETVAL(j, data, length, r) { const char *c; int fieldlen; + const char *on = "", *off = ""; + c = memchr(data, '=', length); if (!c) { log_error("Invalid field."); @@ -360,19 +366,31 @@ static int output_verbose( } fieldlen = c - (const char*) data; - if ((flags & OUTPUT_SHOW_ALL) || (length < PRINT_THRESHOLD && utf8_is_printable(data, length))) { - fprintf(f, " %.*s=", fieldlen, (const char*)data); + if (flags & OUTPUT_COLOR && startswith(data, "MESSAGE=")) { + on = ANSI_HIGHLIGHT_ON; + off = ANSI_HIGHLIGHT_OFF; + } + + if (flags & OUTPUT_SHOW_ALL || + (((length < PRINT_THRESHOLD) || flags & OUTPUT_FULL_WIDTH) && utf8_is_printable(data, length))) { + fprintf(f, " %s%.*s=", on, fieldlen, (const char*)data); print_multiline(f, 4 + fieldlen + 1, 0, OUTPUT_FULL_WIDTH, 0, c + 1, length - fieldlen - 1); + fputs(off, f); } else { char bytes[FORMAT_BYTES_MAX]; - fprintf(f, " %.*s=[%s blob data]\n", + fprintf(f, " %s%.*s=[%s blob data]%s\n", + on, (int) (c - (const char*) data), (const char*) data, - format_bytes(bytes, sizeof(bytes), length - (c - (const char *) data) - 1)); + format_bytes(bytes, sizeof(bytes), length - (c - (const char *) data) - 1), + off); } } + if (r < 0) + return r; + if (flags & OUTPUT_CATALOG) print_catalog(f, j); @@ -426,12 +444,12 @@ static int output_export( (unsigned long long) monotonic, sd_id128_to_string(boot_id, sid)); - SD_JOURNAL_FOREACH_DATA(j, data, length) { + JOURNAL_FOREACH_DATA_RETVAL(j, data, length, r) { /* We already printed the boot id, from the data in * the header, hence let's suppress it here */ if (length >= 9 && - memcmp(data, "_BOOT_ID=", 9) == 0) + hasprefix(data, "_BOOT_ID=")) continue; if (!utf8_is_printable(data, length)) { @@ -455,6 +473,9 @@ static int output_export( fputc('\n', f); } + if (r < 0) + return r; + fputc('\n', f); return 0; @@ -583,7 +604,7 @@ static int output_json( return -ENOMEM; /* First round, iterate through the entry and count how often each field appears */ - SD_JOURNAL_FOREACH_DATA(j, data, length) { + JOURNAL_FOREACH_DATA_RETVAL(j, data, length, r) { const char *eq; char *n; unsigned u; @@ -617,6 +638,9 @@ static int output_json( } } + if (r < 0) + return r; + separator = true; do { done = true; @@ -898,15 +922,15 @@ finish: int add_matches_for_unit(sd_journal *j, const char *unit) { int r; - _cleanup_free_ char *m1 = NULL, *m2 = NULL, *m3 = NULL; + char *m1, *m2, *m3, *m4; 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; + m1 = strappenda("_SYSTEMD_UNIT=", unit); + m2 = strappenda("COREDUMP_UNIT=", unit); + m3 = strappenda("UNIT=", unit); + m4 = strappenda("OBJECT_SYSTEMD_UNIT=", unit); (void)( /* Look for messages from the service itself */ @@ -914,45 +938,59 @@ int add_matches_for_unit(sd_journal *j, const char *unit) { /* 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, "MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1", 0)) || + (r = sd_journal_add_match(j, "_UID=0", 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)) + (r = sd_journal_add_match(j, m3, 0)) || + + /* Look for messages from authorized daemons about this service */ + (r = sd_journal_add_disjunction(j)) || + (r = sd_journal_add_match(j, "_UID=0", 0)) || + (r = sd_journal_add_match(j, m4, 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; + char *m1, *m2, *m3, *m4; + char muid[sizeof("_UID=") + DECIMAL_STR_MAX(uid_t)]; 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; + m1 = strappenda("_SYSTEMD_USER_UNIT=", unit); + m2 = strappenda("USER_UNIT=", unit); + m3 = strappenda("COREDUMP_USER_UNIT=", unit); + m4 = strappenda("OBJECT_SYSTEMD_USER_UNIT=", unit); + sprintf(muid, "_UID=%lu", (unsigned long) uid); (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)) || + (r = sd_journal_add_match(j, muid, 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)) || + (r = sd_journal_add_match(j, muid, 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)) + (r = sd_journal_add_match(j, muid, 0)) || + (r = sd_journal_add_match(j, "_UID=0", 0)) || + + /* Look for messages from authorized daemons about this service */ + (r = sd_journal_add_disjunction(j)) || + (r = sd_journal_add_match(j, m4, 0)) || + (r = sd_journal_add_match(j, muid, 0)) || + (r = sd_journal_add_match(j, "_UID=0", 0)) ); return r; } @@ -997,7 +1035,7 @@ int show_journal_by_unit( _cleanup_journal_close_ sd_journal*j = NULL; int r; - int jflags = SD_JOURNAL_LOCAL_ONLY | system * SD_JOURNAL_SYSTEM_ONLY; + int jflags = SD_JOURNAL_LOCAL_ONLY | system * SD_JOURNAL_SYSTEM; assert(mode >= 0); assert(mode < _OUTPUT_MODE_MAX);