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);