RousselTMLEARNING

Article · OpenObserve: from discovery to expertise

Exploring data: SQL, PromQL and VRL

1. Searching with SQL #

The common language for logs and traces.

Useful queries #

All these queries were run on OpenObserve 1.1.2.

-- Filter on a field
SELECT * FROM commandes WHERE level = 'error'

-- Search text in a field
SELECT * FROM commandes WHERE str_match(message, 'banque')

-- Search all full-text fields
SELECT * FROM commandes WHERE match_all('banque')

-- Aggregate
SELECT service, count(*) AS n, avg(duree_ms) AS moy
FROM commandes GROUP BY service ORDER BY n DESC

-- Per-minute chart
SELECT histogram(_timestamp, '1 minute') AS t, count(*) AS n
FROM commandes GROUP BY t ORDER BY t

-- Percentile
SELECT approx_percentile_cont(duree_ms, 0.95) AS p95 FROM commandes
FunctionUse
str_match(field, 'x')The field contains x
match_all('x')Search in the full-text fields of the stream
histogram(_timestamp, '1 minute')Splits time for charts
approx_percentile_cont(c, 0.95)Approximate percentile

2. PromQL for metrics #

Reusing your Prometheus queries.

A compatible API #

OpenObserve exposes the Prometheus query API under /api/<organization>/prometheus, so Grafana can connect to it like a Prometheus.

curl -s -u 'root@example.com:Complexpass#123' \
  'http://localhost:5080/api/default/prometheus/api/v1/query?query=cpu_usage' | jq .data.result

3. Optimizing a stream #

Indexes, partitions and retention.

Stream settings #

curl -u 'root@example.com:Complexpass#123' -X PUT \
  -H 'Content-Type: application/json' \
  'http://localhost:5080/api/default/streams/commandes/settings?type=logs' \
  -d '{
    "data_retention": 30,
    "full_text_search_keys": {"add": ["message"]},
    "index_fields": {"add": ["service"]},
    "partition_keys": {"add": [{"field": "level", "types": "value"}]}
  }'
SettingEffectFor which fields?
data_retentionStream retention, in days–
full_text_search_keysFields covered by match_allThe message
index_fieldsIndex on a searched fieldIdentifier, service
partition_keysSplits files by valueLow cardinality: level, environment
Partitioning on a highly varied field (request ID, user) creates a multitude of small files and slows everything down. Keep partitions for fields with few distinct values.

4. Transforming with VRL #

Functions at read or write time.

A function #

Functions are written in VRL, the Vector language. They can run at read time, or be applied at ingestion through a pipeline. A function must end with ., which returns the event.

curl -u 'root@example.com:Complexpass#123' \
  -H 'Content-Type: application/json' \
  http://localhost:5080/api/default/functions \
  -d '{"name":"marque_grave","function":".grave = true\n.","params":"row","transType":0}'
# {"code":200,"message":"Function saved successfully"}

To try it at read time, pass it base64-encoded in query_fn: the grave field then appears in results without being stored.

5. Dashboards and traces #

Exploring in the UI.

Dashboards #

Panels rely on a SQL or PromQL query, with variables to filter by service or environment. Dashboards export to JSON: keep them under version control.

Traces #

The Traces menu lists requests and shows their timeline. To go from a log to its trace, have your logs carry trace_id: the OpenTelemetry SDK does it for you when the call runs within a trace.

📄 Exploring data in OpenObserve: SQL, PromQL and VRL →

My progress

  • ⏱ Estimated time : ≈ 8 min

Sign in to track your progress and take notes. Sign in

💬 Ask a question

Recommended Articles

Installing OpenObserve and ingesting your first data

Install OpenObserve with Docker Compose or the binary, configure it with its ZO_* variables, send...

Grafana : maîtriser les requêtes (PromQL, LogQL, SQL et expressions)

Construire des requêtes efficaces dans Grafana : éditeur de requêtes, Query Inspector, PromQL, Lo...

OpenObserve: architecture and concepts

Understanding OpenObserve: Parquet storage, deployment modes, roles (router, ingester, querier, c...

Sending logs, metrics and traces to OpenObserve

OpenObserve receiving endpoints: JSON, bulk, OTLP with the OpenTelemetry Collector, Prometheus re...

Dynatrace : Différences entre SQL Modifications, SQL Queries or Procedures, et SQL Transactions

Cet article détaille les différences entre trois concepts essentiels dans l'exécution des instruc...

Alerts and pipelines in OpenObserve

Create a template, a destination and an alert, avoid the SSRF webhook block and process data with...

OpenObserve in production: best practices

Choose your deployment mode, organize streams, secure, back up and monitor OpenObserve in product...

Data streams et templates Elasticsearch : component templates, index templates et séries temporelles

Gérer les données horodatées avec les data streams : index templates et component templates, conv...

Indexing and searching in OpenSearch: mapping, DSL, PPL and SQL

Declare an index template, index with bulk, search with the Query DSL, aggregate and query with P...

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!