Collect the logs of the local Docker containers
- docker.go follows every running container through the Docker API (events + logs with follow), resumes after a restart from the last position saved in /data/docker-state.json, reads DOCKER_BACKFILL (1h) of history for new containers, strips terminal color codes and guesses the severity from the line (JSON, logfmt, [ERROR], ERROR ...). - Logs carry source_type=docker, container, container_id, image, compose_project, compose_service and stream; host is the Docker host. - Settings > Sources: one switch per container (grouped by compose project), enable/disable all, follow new containers automatically. Choices are saved per compose service in /data/docker.json. - Source filter (syslog / docker) in the filter bar and the live view. - docker-compose: read-only docker-socket-proxy; Logstream and the proxy are labelled logstream.exclude=true and never collected. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
aad0fb7c16
commit
085095c46f
12 files changed
+974
-10
No files matched your search
@@ -35,6 +35,9 @@ type Entry struct {
|
||||
Source string // sender IP address
|
||||
Proto string // udp or tcp
|
||||
HostIP string // original host value when it was an IP resolved through DNS
|
||||
|
||||
SourceType string // "syslog" or "docker"
|
||||
Extra map[string]string // additional fields (docker: container, image, …)
|
||||
}
|
||||
|
||||
// Record returns the entry in the shape stored in VictoriaLogs and returned by the API.
|
||||
@@ -65,6 +68,14 @@ func (e *Entry) Record() map[string]string {
|
||||
if e.HostIP != "" {
|
||||
r["host_ip"] = e.HostIP
|
||||
}
|
||||
if e.SourceType != "" {
|
||||
r["source_type"] = e.SourceType
|
||||
}
|
||||
for k, v := range e.Extra {
|
||||
if v != "" {
|
||||
r[k] = v
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
@@ -81,7 +92,7 @@ func ParseSyslog(raw []byte, source, proto string, now time.Time) *Entry {
|
||||
if !utf8.ValidString(s) {
|
||||
s = strings.ToValidUTF8(s, "\uFFFD")
|
||||
}
|
||||
e := &Entry{Time: now, Received: now, Host: source, Source: source, Proto: proto}
|
||||
e := &Entry{Time: now, Received: now, Host: source, Source: source, Proto: proto, SourceType: "syslog"}
|
||||
e.setPri(13) // user.notice, the RFC 3164 default
|
||||
|
||||
if len(s) > 2 && s[0] == '<' {
|
||||
|
||||
Reference in new issue
Block a user