Problem
vlagent's Kubernetes collector parses the CRI stdout/stderr marker but discards it, so logs cannot be filtered by output stream at query time. Alerting/querying can only match on _msg with regular expressions, which forces VictoriaLogs to scan the entire log stream (mostly stdout info/debug noise) just to find the rare error/panic line.
Expected behavior
Store the container output stream (the CRI stdout/stderr marker) as a dedicated, searchable field so it can be used as a cheap pre-filter, e.g.:
_time: 2m
| kubernetes.pod_labels.app:=my-app
| stream:=stderr
| _msg:~"panic:"
This lets alerting rules (and any query) narrow down to stderr before running the expensive _msg regex, instead of matching against the whole stdout+stderr flow.
Current behavior
In app/vlagent/kubernetescollector/processor.go, parseCRILine reads the stream marker into criLine.stream (streamStdout / streamStderr), but it is used only to pick the correct partial-line merge buffer (partialCRIStdout / partialCRIStderr) in TryAddLine. After that the stream value is dropped and never added to the log fields:
parseCRILine — processor.go:496-538 (stream parsed here)
TryAddLine — processor.go:141-149 (stream used only for joinPartialLines)
addLineInternal / addRow — processor.go:225-266 (only _msg, parsed JSON fields, klog fields and pod metadata are written; no stream field)
As a result, the only stream-related knob is -kubernetesCollector.streamFields, which configures VictoriaLogs _stream fields (default kubernetes.container_name,kubernetes.pod_name,kubernetes.pod_namespace) and has nothing to do with stdout/stderr.
Why it matters
Sending errors/panics/500s to stderr while normal logs go to stdout is a common, useful contract, but right now that separation is lost on ingestion. Without a stream field, every error/panic alert must run a regex over the full stdout+stderr flow, which is the most expensive operation for VictoriaLogs and grows with log volume. A stream:=stderr pre-filter would reduce the scanned data by ~99% for typical applications.
Proposed solution
Add support for preserving the output stream as a field. For example:
- always emit
stream with value stdout or stderr from the parsed CRI marker; and/or
- gate it behind a flag such as
-kubernetesCollector.includeStream (default false) for backward compatibility.
References
Problem
vlagent's Kubernetes collector parses the CRIstdout/stderrmarker but discards it, so logs cannot be filtered by output stream at query time. Alerting/querying can only match on_msgwith regular expressions, which forces VictoriaLogs to scan the entire log stream (mostlystdoutinfo/debug noise) just to find the rare error/panic line.Expected behavior
Store the container output stream (the CRI
stdout/stderrmarker) as a dedicated, searchable field so it can be used as a cheap pre-filter, e.g.:This lets alerting rules (and any query) narrow down to
stderrbefore running the expensive_msgregex, instead of matching against the wholestdout+stderrflow.Current behavior
In
app/vlagent/kubernetescollector/processor.go,parseCRILinereads the stream marker intocriLine.stream(streamStdout/streamStderr), but it is used only to pick the correct partial-line merge buffer (partialCRIStdout/partialCRIStderr) inTryAddLine. After that the stream value is dropped and never added to the log fields:parseCRILine—processor.go:496-538(stream parsed here)TryAddLine—processor.go:141-149(stream used only forjoinPartialLines)addLineInternal/addRow—processor.go:225-266(only_msg, parsed JSON fields, klog fields and pod metadata are written; nostreamfield)As a result, the only
stream-related knob is-kubernetesCollector.streamFields, which configures VictoriaLogs_streamfields (defaultkubernetes.container_name,kubernetes.pod_name,kubernetes.pod_namespace) and has nothing to do with stdout/stderr.Why it matters
Sending errors/panics/500s to
stderrwhile normal logs go tostdoutis a common, useful contract, but right now that separation is lost on ingestion. Without astreamfield, every error/panic alert must run a regex over the full stdout+stderr flow, which is the most expensive operation for VictoriaLogs and grows with log volume. Astream:=stderrpre-filter would reduce the scanned data by ~99% for typical applications.Proposed solution
Add support for preserving the output stream as a field. For example:
streamwith valuestdoutorstderrfrom the parsed CRI marker; and/or-kubernetesCollector.includeStream(defaultfalse) for backward compatibility.References
app/vlagent/kubernetescollector/processor.go