Host system logs source (systemd journal or /var/log)

New source, off by default and switched in Settings > Sources, that
collects the system logs of the machine hosting the stack:
- reads the systemd journal files directly (pure Go reader, no
  journalctl in the image), from /var/log/journal and /run/log/journal
  mounted read-only under /host;
- falls back to following the text files of /var/log (syslog,
  messages, *.log) on hosts without journald;
- positions saved in /data/hostlogs-state.json, HOST_LOGS_BACKFILL
  read when the source is turned on;
- source_type "host", selectable in the Source filter;
- compose mounts and group_add (HOST_LOGS_GID, adm by default), docs.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
cedricandClaude Opus 5.5 committed 2026-10-03 10:05:38 +02:00
1 parent cb2c2c5200
commit 30018e09e2
12 files changed
+1029 -9

No files matched your search

+5 -5
View File
@@ -17,7 +17,7 @@ type Filter struct {
Host string
App string
Severity int // highest severity number included (0 = emerg … 7 = debug), -1 = all
Source string // "syslog", "docker" or "" for all
Source string // "syslog", "docker", "host" or "" for all
}
var rangeDurations = map[string]time.Duration{
@@ -119,10 +119,10 @@ func (f Filter) filterExpr() string {
parts = append(parts, "app:="+strconv.Quote(f.App))
}
switch f.Source {
case "docker":
parts = append(parts, `source_type:="docker"`)
case "docker", "host":
parts = append(parts, `source_type:=`+strconv.Quote(f.Source))
case "syslog": // also matches logs stored before source_type existed
parts = append(parts, `!(source_type:="docker")`)
parts = append(parts, `!(source_type:in("docker","host"))`)
}
if f.Severity >= 0 && f.Severity < 7 {
names := make([]string, 0, 8)
@@ -209,7 +209,7 @@ func (m *Matcher) Match(e *Entry) bool {
if m.f.App != "" && e.App != m.f.App {
return false
}
if (m.f.Source == "docker") != (e.SourceType == "docker") && m.f.Source != "" {
if m.f.Source != "" && m.f.Source != e.SourceType {
return false
}
if m.f.Severity >= 0 && e.SevNum > m.f.Severity {