Skip to main content
This page ships container logs from a Linux host to Rootprint over OTLP. Vector reads the Docker daemon socket: it auto-discovers containers and attaches container.name, container.image.name, and friends with no extra wiring.
This page collects every container’s stdout — Vector via the Docker daemon socket, the Collector via on-disk container logs. To run an agent as a container that tails specific files you bind-mount in, see the agent pages: Vector, OpenTelemetry Collector, Fluent Bit.

Prerequisites

  • A running Rootprint instance and the host it serves on — you’ll substitute it for <your-rootprint>.
  • A Linux host with Docker (and Docker Compose for the examples below).
  • A log agent: Vector or the OpenTelemetry Collector.
  • An ingest API key scoped to your target index. See API keys.
Mounting /var/run/docker.sock into a container lets it enumerate and inspect every container on the host. This is standard for log collectors that use the Docker API. The mount below is read-only (:ro).
1

Create the Vector config

Save this as vector.yaml next to your docker-compose.yml. Replace <your-rootprint> with your Rootprint host and <your-ingest-token> with the API key.
2

Add the Vector service to your compose file

Drop this service alongside your existing ones. The Vector container reads every other container’s logs through the Docker socket. No changes needed to your application services.
The container_name and the exclude_containers value in vector.yaml must match. That’s how Vector skips its own logs. Change one, change the other.
3

Start the Vector service

4

Send a test log line

Run a throwaway container that prints one line and exits. Vector picks it up from the daemon and ships it with service.name set to the container’s name.
5

Verify in Rootprint

Open Search, pick otel-logs-v0_9 from the index selector, and query for hello from rootprint. The record typically arrives within 5 seconds (one batch interval). service.name reads rootprint-smoke-test; attributes.container.image.name reads alpine.

What the remap does

Two remap transforms run in sequence. enrich infers a severity level from the message body. to_otlp packs the message and the Docker-supplied metadata into the OTLP wire format that Rootprint’s ingest endpoint expects.

Severity inference

The message body is lowercased and matched against two pattern families:
  • error, fatal, panic, or exception (word-boundary) → severityText: ERROR (severity number 17).
  • warn / warning, deprecated, or retryseverityText: WARN (13).
  • Everything else → severityText: INFO (9).
DEBUG is not inferred. Emit debug records through an OpenTelemetry SDK that sets severityNumber itself; the OTLP record carries that value through unchanged.

Apps that emit JSON

If a container writes structured JSON to stdout, the body arrives as a string but its content is JSON. Add a parse_json step in enrich and assign parsed fields to attributes. The OTLP attribute list takes them as-is.

What you get in Rootprint

service.name is derived from the container’s name (with the leading / Docker prefixes stripped) when using Vector; it is not set automatically by the OTEL Collector path. Per-event attributes by agent: The Vector path populates all rows. The OTEL Collector path populates container.id, container.runtime, and severity only; it cannot resolve container.name or container.image.name from the json-file path without the Docker socket. Container labels are not promoted by default. To promote a specific label with Vector, add one line to the to_otlp remap before the . = { ... } assignment:

Troubleshooting

  • 401 from Rootprint: the Authorization header is missing or the token is wrong. Check the token value in your config.
  • 403 from Rootprint: the ingest API key is invalid, unknown, or revoked. Create a new one in Settings → API keys. A key scoped to a different index does not return 403 — it writes there silently, so check the key’s index if records land somewhere unexpected.
  • 413 from Rootprint: the batch is too large. Lower max_bytes (Vector) or add send_batch_max_size to the batch processor (OTEL Collector).
  • 415 from Rootprint: the Content-Type is not application/x-protobuf. Both agents set this automatically; if you see a 415, check for a proxy stripping headers.