Berserk Docs

Loki clients

Send logs to Berserk with Grafana Alloy, Promtail or Vector

Berserk accepts Loki push requests at POST /loki/api/v1/push. Copy your installation's Loki Base URL from Settings → Endpoints. If the address is missing, ask your installation administrator for it. Use a Berserk ingest token as the bearer token; its routing determines the database and destination table. A Loki tenant header does not select a Berserk database.

Grafana Alloy

Add a loki.write component and connect your existing log source's forward_to to loki.write.berserk.receiver. The url takes the full push URL, including the path:

loki.write "berserk" {
  endpoint {
    url = "https://<your-loki-host>/loki/api/v1/push"
    bearer_token = "<ingest token>"
    remote_timeout = "30s"
  }
}

For example, a file source can feed this writer:

loki.source.file "app" {
  targets = [{
    __path__ = "/var/log/my-app/*.log",
    service_name = "my-app",
  }]
  forward_to = [loki.write.berserk.receiver]
}

Existing Promtail installations

Replace or add a client in your existing Promtail configuration. Keep your scrape_configs and positions file. This is a client fragment:

clients:
  - url: https://<your-loki-host>/loki/api/v1/push
    bearer_token: "<ingest token>"
    timeout: 30s

Vector

Connect your existing log source to this sink by replacing my_logs. Vector's endpoint takes the base URL and appends the push path:

sinks:
  berserk:
    type: loki
    inputs: [my_logs]
    endpoint: https://<your-loki-host>
    auth:
      strategy: bearer
      token: "<ingest token>"
    labels:
      service_name: my-app
    encoding:
      codec: text
    request:
      timeout_secs: 30

Wire format and responses

Send Content-Type: application/json for a Loki push JSON envelope, with streams, stream labels and timestamp/string pairs. Timestamps are decimal nanoseconds encoded as strings. Arbitrary JSON log objects are not this envelope.

For Protobuf, use Content-Type: application/x-protobuf and Snappy block compression. The Snappy encoding is part of the Loki push format, without a Content-Encoding header. Alloy and Promtail provide this encoding themselves.

A successful request returns 204 with no body, or 202 with no body when the installation acknowledges before storage. An acknowledgment is not a query result; follow delivery semantics for retries and buffering.

Label mapping

Recognized labels become resource attributes; other labels become log record attributes. Severity labels set the record's severity, and exporter is discarded.

Loki labelBerserk resource attribute
service_name, serviceservice.name
service_namespaceservice.namespace
service_instance_id, instanceservice.instance.id
namespace, pod, container, node_namek8s.namespace.name, k8s.pod.name, k8s.container.name, k8s.node.name
k8s_namespace_name, k8s_pod_name, k8s_container_name, k8s_cluster_nameCorresponding k8s.*.name attribute
k8s_deployment_name, k8s_replicaset_name, k8s_statefulset_name, k8s_daemonset_name, k8s_cronjob_name, k8s_job_name, k8s_node_nameCorresponding k8s.*.name attribute
container_namecontainer.name
cloud_availability_zone, cloud_regioncloud.availability_zone, cloud.region
deployment_environment_namedeployment.environment.name
filenamelog.file.path

job supplies service.name when no explicit service label exists. A job of namespace/service also supplies service.namespace. level sets severity. Structured metadata becomes record attributes. Underscores become dots only where the resulting key starts with a recognized OpenTelemetry prefix: service., k8s., host., container., cloud., deployment., process., os., log., http., net. or telemetry.. Other keys retain their spelling.

Send and find a test log

Replace the host and token, then run this command. Its timestamp is generated when you run it:

curl --fail-with-body -w '\nHTTP %{http_code}\n' \
  'https://<your-loki-host>/loki/api/v1/push' \
  -H 'Authorization: Bearer <ingest token>' \
  -H 'Content-Type: application/json' \
  -d '{"streams":[{"stream":{"service_name":"ingest-test","level":"info"},"values":[["'"$(date +%s)"'000000000","Hello from Berserk"]]}]}'

In Berserk, open the token's database and the destination table configured for logs. Use a recent time window and filter service.name == "ingest-test". If no record appears, check the token's routing in Settings → Databases → Tokens and the shipper's export errors.

On this page