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

+8 -1
View File
@@ -1,4 +1,4 @@
// Logstream: a syslog (UDP/TCP) sink stored in VictoriaLogs,
// Logstream: a syslog (UDP/TCP), Docker and host system logs sink stored in VictoriaLogs,
// with a web interface to browse and search the logs.
package main
@@ -38,6 +38,8 @@ type config struct {
dockerLogs bool
dockerHost string
backfill time.Duration
hostRoot string
hostFill time.Duration
batchSize int
queueSize int
flushEvery time.Duration
@@ -89,6 +91,8 @@ func main() {
dockerLogs: getenvBool("DOCKER_LOGS", false),
dockerHost: getenv("DOCKER_HOST", "unix:///var/run/docker.sock"),
backfill: getenvDuration("DOCKER_BACKFILL", time.Hour),
hostRoot: getenv("HOST_LOGS_ROOT", "/host"),
hostFill: getenvDuration("HOST_LOGS_BACKFILL", time.Hour),
batchSize: getenvInt("BATCH_SIZE", 1000),
queueSize: getenvInt("QUEUE_SIZE", 100000),
flushEvery: time.Duration(getenvInt("FLUSH_MS", 1000)) * time.Millisecond,
@@ -139,6 +143,9 @@ func main() {
log.Printf("docker logs enabled through %s", cfg.dockerHost)
}
}
// System logs of the host (journal or /var/log), off until enabled in Settings > Sources.
api.host = NewHostLogs(cfg.hostRoot, cfg.dataDir, cfg.hostFill, sink)
go api.host.Run(ctx)
api.Routes(mux)
mux.Handle("GET /", http.FileServer(http.FS(static)))