Resolve host IPs through DNS, add purge, French date format by default

- Reverse DNS (cached PTR lookups): IP hosts are stored with their name
  in 'host' and the IP in 'host_ip'; older IP-only logs are resolved on
  display and the host filter shows 'name (IP)'. RDNS / DNS_SERVER env.
- Settings > Danger zone: delete all logs (type PURGE to confirm) through
  VictoriaLogs /delete/run_task; -delete.enable added to docker-compose.
  ALLOW_PURGE env to disable it.
- Remove the custom YYYY-MM-DD - HH:MM:SS:mmm format; default is now the
  usual French display DD/MM/YYYY HH:MM:SS.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
cedricandClaude Opus 5.5 committed 2026-09-28 15:39:53 +02:00
1 parent 85701a9119
commit 7a706eeb82
11 files changed
+455 -21

No files matched your search

+24 -1
View File
@@ -15,6 +15,7 @@ import (
"os/signal"
"path/filepath"
"strconv"
"strings"
"syscall"
"time"
_ "time/tzdata" // embedded time zones: TZ works without a system package
@@ -30,6 +31,9 @@ type config struct {
dataDir string
authUser string
authPass string
rdns bool
dnsServer string
allowPurge bool
batchSize int
queueSize int
flushEvery time.Duration
@@ -49,6 +53,16 @@ func getenvInt(key string, def int) int {
return def
}
func getenvBool(key string, def bool) bool {
switch strings.ToLower(os.Getenv(key)) {
case "1", "true", "yes", "on":
return true
case "0", "false", "no", "off":
return false
}
return def
}
func main() {
cfg := config{
syslogAddr: getenv("SYSLOG_ADDR", ":5514"),
@@ -57,6 +71,9 @@ func main() {
dataDir: getenv("DATA_DIR", "/data"),
authUser: os.Getenv("AUTH_USER"),
authPass: os.Getenv("AUTH_PASS"),
rdns: getenvBool("RDNS", true),
dnsServer: os.Getenv("DNS_SERVER"),
allowPurge: getenvBool("ALLOW_PURGE", true),
batchSize: getenvInt("BATCH_SIZE", 1000),
queueSize: getenvInt("QUEUE_SIZE", 100000),
flushEvery: time.Duration(getenvInt("FLUSH_MS", 1000)) * time.Millisecond,
@@ -78,7 +95,13 @@ func main() {
}()
hub := NewHub()
rdns := NewReverseDNS(cfg.rdns, cfg.dnsServer)
sink := func(e *Entry) {
// Host sent as an IP (or no host in the header): replace it with its DNS name.
// A new IP waits at most 300 ms; slower lookups finish in the background.
if name := rdns.Lookup(e.Host, 300*time.Millisecond); name != "" {
e.HostIP, e.Host = e.Host, name
}
store.Enqueue(e)
hub.Publish(e)
}
@@ -91,7 +114,7 @@ func main() {
log.Fatal(err)
}
mux := http.NewServeMux()
api := &API{store: store, hub: hub, tags: tags}
api := &API{store: store, hub: hub, tags: tags, rdns: rdns, allowPurge: cfg.allowPurge}
api.Routes(mux)
mux.Handle("GET /", http.FileServer(http.FS(static)))