@cryptotaxi247 / netdata-1 / commits / 7a9f4282e

Journal updates (#16189)

* add column ND_JOURNAL_FILE showing the file each log line belongs to * ensure log timestamps are unique

Costa Tsaousis committed Oct 13, 2023 at 23:54 UTC 7a9f4282e611be17c4976491a067daeab5604179
1 file changed +39 -8
collectors/systemd-journal.plugin/systemd-journal.c
+39 -8
@@ -129,6 +129,9 @@ int fstat64(int fd, struct stat64 *buf) {
129 #define JOURNAL_PARAMETER_DELTA "delta"
130 #define JOURNAL_PARAMETER_TAIL "tail"
131
132 +#define JOURNAL_KEY_ND_JOURNAL_FILE "ND_JOURNAL_FILE"
133 +#define JOURNAL_KEY_ND_JOURNAL_PROCESS "ND_JOURNAL_PROCESS"
134 +
135 #define JOURNAL_DEFAULT_SLICE_MODE true
136 #define JOURNAL_DEFAULT_DIRECTION FACETS_ANCHOR_DIRECTION_BACKWARD
137
@@ -313,6 +316,8 @@ typedef struct function_query_status {
316 } FUNCTION_QUERY_STATUS;
317
318 struct journal_file {
319 + const char *filename;
320 + size_t filename_len;
321 STRING *source;
322 SD_JOURNAL_FILE_SOURCE_TYPE source_type;
323 usec_t file_last_modified_ut;
@@ -377,6 +382,8 @@ static inline size_t netdata_systemd_journal_process_row(sd_journal *j, FACETS *
382 const void *data;
383 size_t length, bytes = 0;
384
385 + facets_add_key_value_length(facets, JOURNAL_KEY_ND_JOURNAL_FILE, sizeof(JOURNAL_KEY_ND_JOURNAL_FILE) - 1, jf->filename, jf->filename_len);
386 +
387 SD_JOURNAL_FOREACH_DATA(j, data, length) {
388 const char *key, *value;
389 size_t key_length, value_length;
@@ -455,6 +462,9 @@ ND_SD_JOURNAL_STATUS netdata_systemd_journal_query_backward(
462 size_t row_counter = 0, last_row_counter = 0, rows_useful = 0;
463 size_t bytes = 0, last_bytes = 0;
464
465 + usec_t last_usec_from = 0;
466 + usec_t last_usec_to = 0;
467 +
468 ND_SD_JOURNAL_STATUS status = ND_SD_JOURNAL_OK;
469
470 facets_rows_begin(facets);
@@ -475,6 +485,13 @@ ND_SD_JOURNAL_STATUS netdata_systemd_journal_query_backward(
485 break;
486
487 bytes += netdata_systemd_journal_process_row(j, facets, jf, &msg_ut);
488 +
489 + // make sure each line gets a unique timestamp
490 + if(unlikely(msg_ut >= last_usec_from && msg_ut <= last_usec_to))
491 + msg_ut = --last_usec_from;
492 + else
493 + last_usec_from = last_usec_to = msg_ut;
494 +
495 if(facets_row_finished(facets, msg_ut))
496 rows_useful++;
497
@@ -531,6 +548,9 @@ ND_SD_JOURNAL_STATUS netdata_systemd_journal_query_forward(
548 size_t row_counter = 0, last_row_counter = 0, rows_useful = 0;
549 size_t bytes = 0, last_bytes = 0;
550
551 + usec_t last_usec_from = 0;
552 + usec_t last_usec_to = 0;
553 +
554 ND_SD_JOURNAL_STATUS status = ND_SD_JOURNAL_OK;
555
556 facets_rows_begin(facets);
@@ -551,6 +571,13 @@ ND_SD_JOURNAL_STATUS netdata_systemd_journal_query_forward(
571 break;
572
573 bytes += netdata_systemd_journal_process_row(j, facets, jf, &msg_ut);
574 +
575 + // make sure each line gets a unique timestamp
576 + if(unlikely(msg_ut >= last_usec_from && msg_ut <= last_usec_to))
577 + msg_ut = ++last_usec_to;
578 + else
579 + last_usec_from = last_usec_to = msg_ut;
580 +
581 if(facets_row_finished(facets, msg_ut))
582 rows_useful++;
583
@@ -826,20 +853,21 @@ static STRING *string_strdupz_source(const char *s, const char *e, size_t max_le
853
854 static void files_registry_insert_cb(const DICTIONARY_ITEM *item, void *value, void *data __maybe_unused) {
855 struct journal_file *jf = value;
829 - const char *filename = dictionary_acquired_item_name(item);
856 + jf->filename = dictionary_acquired_item_name(item);
857 + jf->filename_len = strlen(jf->filename);
858
859 // based on the filename
860 // decide the source to show to the user
833 - const char *s = strrchr(filename, '/');
861 + const char *s = strrchr(jf->filename, '/');
862 if(s) {
835 - if(strstr(filename, "/remote/"))
863 + if(strstr(jf->filename, "/remote/"))
864 jf->source_type = SDJF_REMOTE;
865 else {
866 const char *t = s - 1;
839 - while(t >= filename && *t != '.' && *t != '/')
867 + while(t >= jf->filename && *t != '.' && *t != '/')
868 t--;
869
842 - if(t >= filename && *t == '.') {
870 + if(t >= jf->filename && *t == '.') {
871 jf->source_type = SDJF_NAMESPACE;
872 jf->source = string_strdupz_source(t + 1, s, SYSTEMD_JOURNAL_MAX_SOURCE_LEN, "namespace-");
873 }
@@ -890,13 +918,13 @@ static void files_registry_insert_cb(const DICTIONARY_ITEM *item, void *value, v
918 else
919 jf->source_type = SDJF_LOCAL | SDJF_OTHER;
920
893 - journal_file_update_msg_ut(filename, jf);
921 + journal_file_update_msg_ut(jf->filename, jf);
922
923 internal_error(true,
924 "found journal file '%s', type %d, source '%s', "
925 "file modified: %"PRIu64", "
926 "msg {first: %"PRIu64", last: %"PRIu64"}",
899 - filename, jf->source_type, jf->source ? string2str(jf->source) : "<unset>",
927 + jf->filename, jf->source_type, jf->source ? string2str(jf->source) : "<unset>",
928 jf->file_last_modified_ut,
929 jf->msg_first_ut, jf->msg_last_ut);
930 }
@@ -2165,7 +2193,7 @@ static void function_systemd_journal(const char *transaction, char *function, in
2193 facets_register_key_name(facets, "_HOSTNAME",
2194 FACET_KEY_OPTION_FACET | FACET_KEY_OPTION_VISIBLE | FACET_KEY_OPTION_FTS);
2195
2168 - facets_register_dynamic_key_name(facets, "ND_JOURNAL_PROCESS",
2196 + facets_register_dynamic_key_name(facets, JOURNAL_KEY_ND_JOURNAL_PROCESS,
2197 FACET_KEY_OPTION_NEVER_FACET | FACET_KEY_OPTION_VISIBLE | FACET_KEY_OPTION_FTS,
2198 netdata_systemd_journal_dynamic_row_id, NULL);
2199
@@ -2190,6 +2218,9 @@ static void function_systemd_journal(const char *transaction, char *function, in
2218 FACET_KEY_OPTION_FACET | FACET_KEY_OPTION_FTS | FACET_KEY_OPTION_TRANSFORM_VIEW,
2219 netdata_systemd_journal_transform_errno, NULL);
2220
2221 + facets_register_key_name(facets, JOURNAL_KEY_ND_JOURNAL_FILE,
2222 + FACET_KEY_OPTION_NEVER_FACET);
2223 +
2224 facets_register_key_name(facets, "SYSLOG_IDENTIFIER",
2225 FACET_KEY_OPTION_FACET | FACET_KEY_OPTION_FTS);
2226