RousselTMLEARNING

Observabilité

Installing OpenObserve and ingesting your first data

Install OpenObserve with Docker Compose or the binary, configure it with its ZO_* variables, send JSON and query it with SQL. Ingestion pitfalls, tested on version 1.1.2.

1. Installing OpenObserve #

Binary or Docker Compose.

With Docker Compose #

services:
  openobserve:
    image: public.ecr.aws/zinclabs/openobserve:latest
    ports:
      - "5080:5080"
    environment:
      ZO_DATA_DIR: /data
      ZO_ROOT_USER_EMAIL: root@example.com
      ZO_ROOT_USER_PASSWORD: Complexpass#123
    volumes:
      - o2-data:/data

volumes:
  o2-data:
docker compose up -d
curl http://localhost:5080/healthz
# {"status":"ok"}

The UI is at http://localhost:5080. Root user credentials are only used at the first startup: changing them later in the file does not change the password.

With the binary #

ZO_ROOT_USER_EMAIL=root@example.com ZO_ROOT_USER_PASSWORD='Complexpass#123' ./openobserve
GLIBC_2.xx not found error? We hit it on Debian 12. Use the -linux-amd64-musl archive, which does not depend on the glibc version.

2. Variables to know #

Everything is configured through the environment.

Main settings #

VariablePurposeDefault
ZO_DATA_DIRLocal data folder./data/openobserve/
ZO_LOCAL_MODESingle nodetrue
ZO_LOCAL_MODE_STORAGEdisk or s3disk
ZO_COMPACT_DATA_RETENTION_DAYSGlobal retention, minimum 3 days3650
ZO_INGEST_ALLOWED_UPTOMaximum age of accepted data, in hours5
ZO_PAYLOAD_LIMITMaximum request size209715200
ZO_NODE_ROLENode rolesall
ZO_TELEMETRYAnonymous telemetry to the vendortrue

Storing in S3 or MinIO #

In local mode you can already move data off the disk. The local folder then keeps the WAL and temporary files.

ZO_LOCAL_MODE: "true"
ZO_LOCAL_MODE_STORAGE: s3
ZO_S3_SERVER_URL: http://minio:9000
ZO_S3_REGION_NAME: us-east-1
ZO_S3_BUCKET_NAME: openobserve
ZO_S3_ACCESS_KEY: minioadmin
ZO_S3_SECRET_KEY: minioadmin
ZO_S3_PROVIDER: minio

3. First ingestion #

Sending and finding events.

Send #

The path is always /api/<organization>/<stream>/_json. The stream is created if it does not exist.

curl -u 'root@example.com:Complexpass#123' \
  -H 'Content-Type: application/json' \
  http://localhost:5080/api/default/commandes/_json \
  -d '[
    {"level":"error","service":"paiement","message":"timeout vers la banque","duree_ms":3100},
    {"level":"info","service":"paiement","message":"ok","duree_ms":120},
    {"level":"info","service":"panier","message":"ok","duree_ms":40}
  ]'
# {"code":200,"status":[{"name":"commandes","successful":3,"failed":0}]}

Query #

The search API expects SQL and a time range in microseconds.

NOW=$(date +%s)
curl -s -u 'root@example.com:Complexpass#123' \
  -H 'Content-Type: application/json' \
  http://localhost:5080/api/default/_search \
  -d "{\"query\":{
        \"sql\":\"SELECT service, count(*) AS n, avg(duree_ms) AS moy FROM commandes GROUP BY service ORDER BY n DESC\",
        \"start_time\":$(( (NOW-3600)*1000000 )),
        \"end_time\":$(( (NOW+60)*1000000 )),
        \"from\":0,\"size\":10}}" | jq .hits

What ingestion transforms #

These results were observed by sending {"Level":"INFO","http":{"status":500},"Tags":["a","b"]}:

SentStoredConsequence
LevellevelNames become lowercase
http.status (nested object)http_statusObjects are flattened with _
Tags: ["a","b"]String "[\"a\",\"b\"]"An array becomes JSON text
The old data pitfall: an event older than 5 hours is refused while still returning HTTP 200. The detail is in the response: "successful":0,"failed":1,"error":"Too old data...". So read the response body when backfilling, and raise ZO_INGEST_ALLOWED_UPTO if needed.

Related articles

OpenObserve: architecture and concepts

Understanding OpenObserve: Parquet storage, deployment modes, roles (router, ingester, querier, compactor, sc…

Sending logs, metrics and traces to OpenObserve

OpenObserve receiving endpoints: JSON, bulk, OTLP with the OpenTelemetry Collector, Prometheus remote write, …

Exploring data in OpenObserve: SQL, PromQL and VRL

Search with SQL, query metrics with PromQL, optimize a stream (indexes, partitions, retention) and transform …

Keep learning

Support us

♥ SUPPORT US

Support RousselTM Learning

Courses, articles, labs and certificates stay free with no intrusive ads. A voluntary contribution, of any amount you choose, pays for hosting, lab environments and new content.

Contribute with PayPal Any amount · card or PayPal accountLearn more
QR code PayPal
Or scan this QR code with your phone

Thank you, every contribution counts!