Skip to content

OpenObserve — Commands & Recipes

Runnable commands, configuration snippets, and troubleshooting recipes for OpenObserve.

Installation

Docker (Single Node)

docker run -d --name openobserve \
  -p 5080:5080 \
  -e ZO_ROOT_USER_EMAIL=[email protected] \
  -e ZO_ROOT_USER_PASSWORD=ComplexPass#123 \
  -e ZO_LOCAL_MODE=true \
  -v $PWD/data:/data \
  openobserve/openobserve:latest

Docker Compose

version: '3'
services:
  openobserve:
    image: openobserve/openobserve:latest
    ports:
      - "5080:5080"
    environment:
      ZO_ROOT_USER_EMAIL: [email protected]
      ZO_ROOT_USER_PASSWORD: ComplexPass#123
      ZO_LOCAL_MODE: "true"
    volumes:
      - o2data:/data
volumes:
  o2data:

Helm (Kubernetes HA)

helm repo add openobserve https://charts.openobserve.ai
helm repo update
helm install openobserve openobserve/openobserve \
  -n openobserve --create-namespace \
  -f values.yaml

Data Ingestion

Send Logs via curl

# JSON log ingestion
curl -u [email protected]:ComplexPass#123 \
  -X POST http://localhost:5080/api/default/mystream/_json \
  -H "Content-Type: application/json" \
  -d '[{"level":"info","message":"Hello from curl","ts":"2026-04-11T00:00:00Z"}]'

Send Logs via Elasticsearch Bulk API

# ES Bulk compatible endpoint
curl -u [email protected]:ComplexPass#123 \
  -X POST "http://localhost:5080/es/default/mystream/_bulk" \
  -H "Content-Type: application/x-ndjson" \
  --data-binary @logs.ndjson

OTel Collector Config

exporters:
  otlphttp:
    endpoint: http://openobserve:5080/api/default
    headers:
      Authorization: "Basic <base64(email:password)>"
      stream-name: otel-logs

service:
  pipelines:
    logs:
      receivers: [otlp]
      exporters: [otlphttp]

Query Examples

SQL Queries (Logs)

-- Search for errors in last 1 hour
SELECT * FROM logs
WHERE body LIKE '%error%'
  AND _timestamp >= NOW() - INTERVAL '1 hour'
ORDER BY _timestamp DESC
LIMIT 100;

-- Top error messages
SELECT body, count(*) as cnt
FROM logs
WHERE severity_text = 'ERROR'
  AND _timestamp >= NOW() - INTERVAL '24 hours'
GROUP BY body
ORDER BY cnt DESC
LIMIT 20;

-- Log volume by stream
SELECT stream_name, count(*) as cnt,
  pg_size_pretty(sum(length(body))) as total_size
FROM logs
WHERE _timestamp >= NOW() - INTERVAL '1 hour'
GROUP BY stream_name;

Operational Recipes

Health Check

curl http://localhost:5080/healthz
# Returns: {"status":"ok"}

Check Storage Usage

curl -u [email protected]:ComplexPass#123 \
  http://localhost:5080/api/default/streams

Kubernetes Operations

# Check pods
kubectl get pods -n openobserve

# View ingester logs
kubectl logs -n openobserve -l role=ingester --tail=50

# View querier logs
kubectl logs -n openobserve -l role=querier --tail=50

# Restart ingesters
kubectl rollout restart statefulset openobserve-ingester -n openobserve

Upgrade

# Docker
docker pull openobserve/openobserve:latest
docker stop openobserve && docker rm openobserve
# Re-run docker run command with same volumes

# Helm
helm repo update openobserve
helm upgrade openobserve openobserve/openobserve -n openobserve -f values.yaml

Sources