Stream CI build logs to your observability backend
Export CI build step logs from a self-managed Legacy Delegate to your own observability backend using any log collector.
When enabled, Harness CI can emit every build step log line as a structured JSON record to the build container's stdout, alongside the standard Harness Log Service. Once those records are written, you can collect and ship them to your observability backend using any log collector of your choice.
This gives you full ownership of your CI log data. You can search, alert on, correlate, and retain build logs in your own infrastructure without changing pipeline YAML and without coupling Harness to any specific telemetry stack.
What you will learn
What dual logging is: How the
HARNESS_LOG_STREAMING_STDOUT_ENABLEDflag enables a parallel stream that mirrors every build step log line as flat JSON.Supported infrastructure: Which delegate and build infrastructure combinations are supported today and what is planned.
Collector setup: How to enable log streaming on your delegate and configure log collection for Kubernetes build infrastructure.
Log schema and queries: The exact JSON fields emitted on each line and example queries you can run in Grafana Loki, Splunk, or Elasticsearch.
Supported infrastructure
Support for CI log streaming depends on your delegate type and build infrastructure:
Self-managed Legacy Delegate
Kubernetes cluster
Supported
A node-level log collector DaemonSet tails build pod container logs.
Self-managed Kubernetes Delegate
Kubernetes cluster
Coming soon
This capability is currently planned for Kubernetes-based builds running on Delegate 3.x.
Harness Cloud (hosted build infrastructure)
N/A
Not applicable
Logs are managed by Harness and are not exposed for external collection.
How it works
When log streaming is enabled, the delegate propagates the flag to every container in every CI build pod it creates. The orchestrator container writes stage-level lines (such as setup, step dispatch, and teardown) as JSON to its own stdout, while each step container writes its stdout and stderr as JSON to its own stdout. Because every line is written to container stdout, the standard node-level path /var/log/pods/<namespace>_harnessci-*/**/*.log captures all records.
Before you begin
This guide assumes:
You have Continuous Integration enabled on your Harness account. Go to Harness CI overview to review account prerequisites and module setup.
You are using a self-managed Legacy Delegate with Kubernetes build infrastructure.
You have permission to update delegate manifests.
You have an observability backend that can receive logs (such as Grafana Loki, Splunk, Datadog, or Elasticsearch).
Step 1: Enable log streaming
Enable log streaming by setting the appropriate environment variables.
For Kubernetes build infrastructure (Legacy Delegate)
Edit your delegate Deployment manifest and add the environment variable HARNESS_LOG_STREAMING_STDOUT_ENABLED=true to the delegate container:
Apply the manifest and wait for the rollout to complete:
For Docker-based delegates
Add the environment variable to your docker run command:
Step 2: Configure log collection
Once log streaming is enabled, you can configure your log collector of choice to tail and forward the log records.
Deploy an OpenTelemetry (OTel) Collector DaemonSet in your cluster to tail the node container logs. The filelog receiver tails container logs under /var/log/pods, and a parser extracts the JSON envelope emitted by Harness CI.
Below is an example snippet for the OTel Collector configuration. Replace <your-namespace> and <your-delegate-name> with your actual values:
Step 3: Verify log streaming
Run a CI pipeline that uses your Kubernetes build infrastructure.
Check your collector DaemonSet logs:
Query your observability backend for logs with
service.name = "harness-ci".
Log format reference
Each CI log line is written as a structured JSON object:
Field reference
timestamp
UTC timestamp in RFC 3339 nanosecond format.
level
Log level: INFO, WARN, ERROR. Note that for Kubernetes build pod stdout, this is currently hardcoded to INFO on the stdout stream. Severity-based filtering can be done on the message content downstream or by relying on the original Harness Log Service.
message
The actual log line content.
logType
Always EXECUTION_LOGS for CI step execution output.
logAbstractions.accountId
Your Harness account identifier.
logAbstractions.orgId
The organization identifier.
logAbstractions.projectId
The project identifier.
logAbstractions.pipelineId
The pipeline identifier.
logAbstractions.runSequence
The run number (or run sequence).
logAbstractions.planExecutionId
The unique execution ID for this pipeline run.
logAbstractions.stageIdentifier
The stage that produced the log.
logAbstractions.stepIdentifier
The identifier of the step that produced this line, or engine for stage-level orchestration lines.
logContext.taskId
The delegate task ID (present when available).
Query examples
The following query examples assume the default service.name tags configured in the steps above.
Grafana Loki (LogQL)
Splunk (SPL)
Elasticsearch (KQL)
Resiliency and data safety
Because log streaming writes logs in parallel to the standard flow, Harness UI logs are completely unaffected if your log collector or observability backend experiences an outage. The collector handles buffering and retries asynchronously.
Log collector restarts
The collector tracks its read position (offset) in each log file. Upon restart, it resumes reading from that offset.
No data lost (as long as files have not been rotated or pruned on disk).
Backend is temporarily down
The collector buffers logs in a sending queue and retries with exponential backoff.
No data lost (within the buffer and retry window).
Backend is down for an extended period
The sending queue becomes full. Once the queue is full, the oldest buffered log entries are dropped.
Logs may be lost on the collector side (only the external copy; Harness UI logs remain fully intact).
Collector crashes
In-memory buffers and queue states are lost.
Minimal data lost (limited to in-flight batches that were not yet flushed to the backend).
Frequently asked questions
Related concepts
Now that you understand CI log streaming, explore related build infrastructure and logging topics:
Set up a Kubernetes cluster build infrastructure: Learn how to configure a self-managed Kubernetes build farm.
Customize delegate logging: Configure log patterns and levels for the delegate process itself.
Last updated
Was this helpful?