diff --git a/containers/container.go b/containers/container.go index 379d350..13e7a47 100644 --- a/containers/container.go +++ b/containers/container.go @@ -1238,6 +1238,11 @@ func (c *Container) ping() map[netaddr.IP]float64 { return rtt } +const ( + logSourceJournald = "journald" + logSourceStdout = "stdout/stderr" +) + func (c *Container) runLogParser(logPath string) { if *flags.DisableLogParsing { return @@ -1257,7 +1262,7 @@ func (c *Container) runLogParser(logPath string) { return } ch := make(chan logparser.LogEntry) - parser := logparser.NewParser(ch, nil, logs.OtelLogEmitter(containerId), logs.MultilineCollectorTimeout, *flags.LogPatternsPerContainer, !*flags.DisableJsonLogParsing, logs.PatternExtractionRateLimiter()) + parser := logparser.NewParser(ch, nil, logs.OtelLogEmitter(containerId, logPath), logs.MultilineCollectorTimeout, *flags.LogPatternsPerContainer, !*flags.DisableJsonLogParsing, logs.PatternExtractionRateLimiter()) reader, err := logs.NewTailReader(proc.HostPath(logPath), ch) if err != nil { klog.Warningln(err) @@ -1276,23 +1281,23 @@ func (c *Container) runLogParser(logPath string) { klog.Warningln(err) return } - parser := logparser.NewParser(ch, nil, logs.OtelLogEmitter(containerId), logs.MultilineCollectorTimeout, *flags.LogPatternsPerContainer, !*flags.DisableJsonLogParsing, logs.PatternExtractionRateLimiter()) + parser := logparser.NewParser(ch, nil, logs.OtelLogEmitter(containerId, logSourceJournald), logs.MultilineCollectorTimeout, *flags.LogPatternsPerContainer, !*flags.DisableJsonLogParsing, logs.PatternExtractionRateLimiter()) stop := func() { JournaldUnsubscribe(c.metadata.systemd.Unit) } klog.InfoS("started journald logparser", "cg", c.cgroup.Id) - c.logParsers["journald"] = logs.NewPipeline(parser, stop) + c.logParsers[logSourceJournald] = logs.NewPipeline(parser, stop) case cgroup.ContainerTypeDocker, cgroup.ContainerTypeContainerd, cgroup.ContainerTypeCrio: if c.metadata.logPath == "" { return } - if parser := c.logParsers["stdout/stderr"]; parser != nil { + if parser := c.logParsers[logSourceStdout]; parser != nil { parser.Stop() - delete(c.logParsers, "stdout/stderr") + delete(c.logParsers, logSourceStdout) } ch := make(chan logparser.LogEntry) - parser := logparser.NewParser(ch, c.metadata.logDecoder, logs.OtelLogEmitter(containerId), logs.MultilineCollectorTimeout, *flags.LogPatternsPerContainer, !*flags.DisableJsonLogParsing, logs.PatternExtractionRateLimiter()) + parser := logparser.NewParser(ch, c.metadata.logDecoder, logs.OtelLogEmitter(containerId, logSourceStdout), logs.MultilineCollectorTimeout, *flags.LogPatternsPerContainer, !*flags.DisableJsonLogParsing, logs.PatternExtractionRateLimiter()) reader, err := logs.NewTailReader(proc.HostPath(c.metadata.logPath), ch) if err != nil { klog.Warningln(err) @@ -1300,7 +1305,7 @@ func (c *Container) runLogParser(logPath string) { return } klog.InfoS("started container logparser", "cg", c.cgroup.Id) - c.logParsers["stdout/stderr"] = logs.NewPipeline(parser, reader.Stop) + c.logParsers[logSourceStdout] = logs.NewPipeline(parser, reader.Stop) } } diff --git a/logs/otel.go b/logs/otel.go index c059d6e..0bc2404 100644 --- a/logs/otel.go +++ b/logs/otel.go @@ -124,11 +124,14 @@ func normalizeTraceContextKey(k string) string { return "" } -func logRecordAttrs(patternHash string, attributes map[string]string) ([]attribute.KeyValue, *trace.TraceID, *trace.SpanID) { +func logRecordAttrs(source, patternHash string, attributes map[string]string) ([]attribute.KeyValue, *trace.TraceID, *trace.SpanID) { var traceId *trace.TraceID var spanId *trace.SpanID - attrs := make([]attribute.KeyValue, 0, len(attributes)+1) + attrs := make([]attribute.KeyValue, 0, len(attributes)+2) attrs = append(attrs, attribute.Key("pattern.hash").String(patternHash)) + if source != "" { + attrs = append(attrs, attribute.Key(LogSourceAttribute).String(source)) + } for k, v := range attributes { switch normalizeTraceContextKey(k) { case traceIdKey: @@ -151,7 +154,9 @@ func logRecordAttrs(patternHash string, attributes map[string]string) ([]attribu return attrs, traceId, spanId } -func OtelLogEmitter(containerId string) logparser.OnMsgCallbackF { +const LogSourceAttribute = "log.source" + +func OtelLogEmitter(containerId, source string) logparser.OnMsgCallbackF { if otelLogger == nil { return nil } @@ -171,7 +176,7 @@ func OtelLogEmitter(containerId string) logparser.OnMsgCallbackF { severityNumber = otelLogs.DEBUG } - attrs, traceId, spanId := logRecordAttrs(patternHash, attributes) + attrs, traceId, spanId := logRecordAttrs(source, patternHash, attributes) otelLogger.Emit( otelLogs.NewLogRecord(otelLogs.LogRecordConfig{ diff --git a/windows/containers/container.go b/windows/containers/container.go index 33db75b..183fbb6 100644 --- a/windows/containers/container.go +++ b/windows/containers/container.go @@ -265,7 +265,7 @@ func (c *Container) eventLogInput() chan logparser.LogEntry { return c.eventLogCh } ch := make(chan logparser.LogEntry, 100) - parser := logparser.NewParser(ch, nil, logs.OtelLogEmitter(c.ID), logs.MultilineCollectorTimeout, *flags.LogPatternsPerContainer, !*flags.DisableJsonLogParsing, logs.PatternExtractionRateLimiter()) + parser := logparser.NewParser(ch, nil, logs.OtelLogEmitter(c.ID, logSourceEventLog), logs.MultilineCollectorTimeout, *flags.LogPatternsPerContainer, !*flags.DisableJsonLogParsing, logs.PatternExtractionRateLimiter()) c.addLogParserLocked(logSourceEventLog, logs.NewPipeline(parser, nil)) c.eventLogCh = ch return ch @@ -279,7 +279,7 @@ func (c *Container) startLogTailer() { defer c.lock.Unlock() c.stopLogParserLocked(logSourceStdout) ch := make(chan logparser.LogEntry, 100) - parser := logparser.NewParser(ch, logparser.DockerJsonDecoder{}, logs.OtelLogEmitter(c.ID), logs.MultilineCollectorTimeout, *flags.LogPatternsPerContainer, !*flags.DisableJsonLogParsing, logs.PatternExtractionRateLimiter()) + parser := logparser.NewParser(ch, logparser.DockerJsonDecoder{}, logs.OtelLogEmitter(c.ID, logSourceStdout), logs.MultilineCollectorTimeout, *flags.LogPatternsPerContainer, !*flags.DisableJsonLogParsing, logs.PatternExtractionRateLimiter()) reader, err := logs.NewTailReader(c.logPath, ch) if err != nil { parser.Stop()