This guide explains how to configure Sawmills to send logs to VictoriaLogs using the OTLP HTTP destination. VictoriaLogs natively supports OTLP log ingestion over HTTP, so no custom destination type is needed — you can use the existing OTLP destination in Sawmills.
VictoriaLogs only supports OTLP over HTTP (not gRPC). Make sure to select HTTP as the protocol when creating the destination.
Prerequisites
- A running VictoriaLogs instance (managed or self-hosted)
- A Sawmills pipeline with a log source configured (e.g., OTLP, Loki, Datadog)
VictoriaLogs Cloud (Managed)
1. Get your VictoriaLogs Cloud credentials
- Log in to VictoriaMetrics Cloud
- Create a VictoriaLogs deployment (type: “Vlogs single”)
- Note the Access endpoint from the deployment overview (e.g.,
https://gw-c21-1a.cloud.victoriametrics.com)
- Go to the Access Tokens tab and copy your deployment access token
2. Create an OTLP destination in Sawmills
Navigate to your pipeline, click + Add Destination, select OTLP, and fill in:
| Field | Value |
|---|
| Name | e.g., victorialogs-cloud |
| Protocol | HTTP |
| Endpoint | https://<your-deployment-endpoint>/insert/opentelemetry |
| Enable Basic Auth | Off |
| Enabled Data Types | Logs only (uncheck Metrics and Traces) |
| Logs Endpoint | Leave empty (Sawmills appends /v1/logs to the base endpoint automatically) |
VictoriaLogs is a log storage backend. Uncheck Metrics and Traces under Enabled Data Types — VictoriaLogs does not accept these signals.
Expand Advanced Options and under Additional Headers, click + Add Header:
| Name | Value |
|---|
Authorization | Bearer <your-access-token> |
Leave the other advanced settings at their defaults:
- Timeout: 30 seconds
- Compression: gzip
4. Deploy and verify
- Click Save, then deploy the pipeline
- Send test logs through your pipeline source
- Verify logs arrive in VictoriaLogs using the Explore tab in VictoriaMetrics Cloud, or query via the API:
curl -s \
"https://<your-deployment-endpoint>/select/logsql/query" \
-H "Authorization: Bearer <your-access-token>" \
--data-urlencode 'query=*' \
--data-urlencode 'limit=10'
VictoriaLogs Self-Hosted
1. Identify your VictoriaLogs endpoint
The default OTLP ingestion endpoint for self-hosted VictoriaLogs is:
http://<victorialogs-host>:9428/insert/opentelemetry
The default port is 9428. Sawmills appends /v1/logs automatically when sending log data.
If VictoriaLogs runs in the same Kubernetes cluster as the Sawmills collector, use the in-cluster DNS:
http://victorialogs.<namespace>.svc.cluster.local:9428/insert/opentelemetry
2. Create an OTLP destination in Sawmills
Navigate to your pipeline, click + Add Destination, select OTLP, and fill in:
| Field | Value |
|---|
| Name | e.g., victorialogs-onprem |
| Protocol | HTTP |
| Endpoint | http://victorialogs.sawmills.svc.cluster.local:9428/insert/opentelemetry |
| Enable Basic Auth | Off |
| Enabled Data Types | Logs only (uncheck Metrics and Traces) |
| Logs Endpoint | Leave empty |
No authentication headers are needed for self-hosted VictoriaLogs (unless you have placed an auth proxy like vmauth in front of it).
3. Deploy and verify
- Click Save, then deploy the pipeline
- Query VictoriaLogs to confirm logs are arriving:
curl -s "http://<victorialogs-host>:9428/select/logsql/query" \
--data-urlencode 'query=* | stats count() as total'
Multi-Tenancy
VictoriaLogs supports multi-tenancy via AccountID and ProjectID HTTP headers. Tenants are created implicitly on first write — no server-side setup required.
When to use multi-tenancy
- Isolate logs by team, environment, or business unit within a shared VictoriaLogs instance
- Separate infrastructure logs from application logs
- Provide per-tenant query isolation (each tenant can only see its own data)
Create a separate OTLP destination for each tenant, all pointing to the same VictoriaLogs endpoint. Under Advanced Options → Additional Headers, set:
| Name | Value |
|---|
AccountID | Tenant ID (uint32, e.g., 1, 2, 3) |
Example setup with two tenants:
Destination 1 — “VL Infra Logs”
| Field | Value |
|---|
| Endpoint | http://victorialogs:9428/insert/opentelemetry |
| Enabled Data Types | Logs only |
| Additional Header | AccountID = 1 |
Destination 2 — “VL App Logs”
| Field | Value |
|---|
| Endpoint | http://victorialogs:9428/insert/opentelemetry |
| Enabled Data Types | Logs only |
| Additional Header | AccountID = 2 |
Then use Sawmills filter rules on each destination to route the right logs to each tenant (e.g., filter by service.name, k8s.namespace.name, or other attributes).
Querying a specific tenant
Pass the same AccountID header when querying to isolate reads:
# Query infra logs (tenant 1)
curl -s "http://<victorialogs-host>:9428/select/logsql/query" \
-H "AccountID: 1" \
--data-urlencode 'query=*' \
--data-urlencode 'limit=10'
# Query app logs (tenant 2)
curl -s "http://<victorialogs-host>:9428/select/logsql/query" \
-H "AccountID: 2" \
--data-urlencode 'query=*' \
--data-urlencode 'limit=10'
If no AccountID header is set, logs are stored and queried under the default tenant (0, 0). ProjectID is an optional second dimension for finer grouping within an account.
Multi-tenancy with VictoriaLogs Cloud
VictoriaMetrics Cloud uses deployment-level isolation — each deployment is a separate tenant. Multi-tenancy via AccountID/ProjectID headers is typically not needed. Create separate Cloud deployments if you need tenant isolation.
How it works
The data flow through Sawmills is:
Your applications → Sawmills Collector → VictoriaLogs
(OTLP HTTP export)
Sawmills uses the standard OpenTelemetry Collector otlphttp exporter to send logs. VictoriaLogs receives them at its /insert/opentelemetry/v1/logs endpoint using protobuf encoding.
What gets preserved:
- All OpenTelemetry resource attributes (e.g.,
service.name, host.name, k8s.*)
- Log severity and body
- Scope name and version
- Sawmills-injected metadata (
sawmills.pipeline_id, sawmills.pipeline_name, sawmills.collector_id)
Log streams: VictoriaLogs automatically uses all OTel resource attributes as log stream identifiers. To customize which fields define a log stream, add the VL-Stream-Fields header (comma-separated field names) under Additional Headers.
Troubleshooting
| Symptom | Cause | Fix |
|---|
| HTTP 401 Unauthenticated | Invalid or missing bearer token (Cloud) | Verify the Authorization header value matches your VictoriaLogs access token |
| HTTP 400 “json encoding isn’t supported” | Endpoint misconfiguration | Ensure you are using the OTLP destination (protobuf), not sending raw JSON |
| Logs not appearing | Wrong endpoint path | Verify the endpoint ends with /insert/opentelemetry (Sawmills appends /v1/logs automatically) |
| Logs in wrong tenant | Missing or wrong AccountID header | Check the Additional Headers section in your destination config |
| High cardinality warning in VL | Too many unique stream combinations | Add a VL-Stream-Fields header to limit which attributes define log streams |
| Export timeout | Network or firewall issue | Check that the collector can reach the VictoriaLogs endpoint; verify TLS settings |