@cryptotaxi247 / netdata-1 / commits / 9a7fe3aa7

systemd-journal; support querying archived files (#18792)

allow supporting multiple extensions for journal files

Costa Tsaousis committed Oct 16, 2024 at 13:29 UTC 9a7fe3aa7b222e9b1b4c1f794760757112da5aa6
3 files changed +40 -9
src/collectors/systemd-journal.plugin/systemd-internals.h
+2
@@ -153,4 +153,6 @@ static inline bool parse_journal_field(const char *data, size_t data_length, con
153
154 void systemd_journal_dyncfg_init(struct functions_evloop_globals *wg);
155
156 +bool is_journal_file(const char *filename, ssize_t len, const char **start_of_extension);
157 +
158 #endif //NETDATA_COLLECTORS_SYSTEMD_INTERNALS_H
src/collectors/systemd-journal.plugin/systemd-journal-files.c
+37 -8
@@ -285,8 +285,8 @@ void journal_file_update_header(const char *filename, struct journal_file *jf) {
285 if(dash_seqnum) {
286 const char *dash_first_msg_ut = strchr(dash_seqnum + 1, '-');
287 if(dash_first_msg_ut) {
288 - const char *dot_journal = strstr(dash_first_msg_ut + 1, ".journal");
289 - if(dot_journal) {
288 + const char *dot_journal = NULL;
289 + if(is_journal_file(filename, -1, &dot_journal) && dot_journal && dot_journal > dash_first_msg_ut) {
290 if(dash_seqnum - at - 1 == 32 &&
291 dash_first_msg_ut - dash_seqnum - 1 == 16 &&
292 dot_journal - dash_first_msg_ut - 1 == 16) {
@@ -392,7 +392,7 @@ static void files_registry_insert_cb(const DICTIONARY_ITEM *item, void *value, v
392
393 char *e = strchr(s, '@');
394 if(!e)
395 - e = strstr(s, ".journal");
395 + is_journal_file(s, -1, (const char **)&e);
396
397 if(e) {
398 const char *d = s;
@@ -572,10 +572,39 @@ static void files_registry_delete_cb(const DICTIONARY_ITEM *item, void *value, v
572 string_freez(jf->source);
573 }
574
575 -void journal_directory_scan_recursively(DICTIONARY *files, DICTIONARY *dirs, const char *dirname, int depth) {
576 - static const char *ext = ".journal";
577 - static const ssize_t ext_len = sizeof(".journal") - 1;
575 +#define EXT_DOT_JOURNAL ".journal"
576 +#define EXT_DOT_JOURNAL_TILDA ".journal~"
577 +
578 +static struct {
579 + const char *ext;
580 + ssize_t len;
581 +} valid_journal_extension[] = {
582 + { .ext = EXT_DOT_JOURNAL, .len = sizeof(EXT_DOT_JOURNAL) - 1 },
583 + { .ext = EXT_DOT_JOURNAL_TILDA, .len = sizeof(EXT_DOT_JOURNAL_TILDA) - 1 },
584 +};
585 +
586 +bool is_journal_file(const char *filename, ssize_t len, const char **start_of_extension) {
587 + if(len < 0)
588 + len = (ssize_t)strlen(filename);
589 +
590 + for(size_t i = 0; i < _countof(valid_journal_extension) ;i++) {
591 + const char *ext = valid_journal_extension[i].ext;
592 + ssize_t elen = valid_journal_extension[i].len;
593 +
594 + if(len > elen && strcmp(filename + len - elen, ext) == 0) {
595 + if(start_of_extension)
596 + *start_of_extension = filename + len - elen;
597 + return true;
598 + }
599 + }
600
601 + if(start_of_extension)
602 + *start_of_extension = NULL;
603 +
604 + return false;
605 +}
606 +
607 +void journal_directory_scan_recursively(DICTIONARY *files, DICTIONARY *dirs, const char *dirname, int depth) {
608 if (depth > VAR_LOG_JOURNAL_MAX_DEPTH)
609 return;
610
@@ -605,7 +634,7 @@ void journal_directory_scan_recursively(DICTIONARY *files, DICTIONARY *dirs, con
634 if (entry->d_type == DT_DIR) {
635 journal_directory_scan_recursively(files, dirs, full_path, depth++);
636 }
608 - else if (entry->d_type == DT_REG && len > ext_len && strcmp(full_path + len - ext_len, ext) == 0) {
637 + else if (entry->d_type == DT_REG && is_journal_file(full_path, len, NULL)) {
638 if(files)
639 dictionary_set(files, full_path, NULL, 0);
640
@@ -623,7 +652,7 @@ void journal_directory_scan_recursively(DICTIONARY *files, DICTIONARY *dirs, con
652 journal_directory_scan_recursively(files, dirs, resolved_path, depth++);
653 }
654 }
626 - else if(S_ISREG(info.st_mode) && len > ext_len && strcmp(full_path + len - ext_len, ext) == 0) {
655 + else if(S_ISREG(info.st_mode) && is_journal_file(full_path, len, NULL)) {
656 if(files)
657 dictionary_set(files, full_path, NULL, 0);
658
src/collectors/systemd-journal.plugin/systemd-journal-watcher.c
+1 -1
@@ -245,7 +245,7 @@ void process_event(Watcher *watcher, int inotifyFd, struct inotify_event *event)
245 "JOURNAL WATCHER: Received unhandled event with mask %u for directory '%s'",
246 event->mask, fullPath);
247 }
248 - else if(len > sizeof(".journal") - 1 && strcmp(&event->name[len - (sizeof(".journal") - 1)], ".journal") == 0) {
248 + else if(is_journal_file(event->name, (ssize_t)len, NULL)) {
249 // It is a file that ends in .journal
250 // add it to our pending list
251 dictionary_set(watcher->pending, fullPath, NULL, 0);