Elasticsearch Query Datasets
Elasticsearch Query datasets define what an Elasticsearch Query device reads from an Elasticsearch or OpenSearch cluster: each is a query of the cluster. They attach to devices of type elasticsearch_query, and in
Collector Types
| Dataset (console title) | Definition | Kind | Definition id | Reads |
|---|---|---|---|---|
| Elasticsearch Query Documents | elasticsearch_query_document_collector | log | 57 | Every document a query matches, in the order of its timestamp, none missed. See Documents. |
| Elasticsearch Query Aggregations | elasticsearch_query_aggregation_collector | metric | 24150 | A count of the documents a query matches per window of time, or a metric of their fields, in buckets of tags. See Aggregations. |
A device runs any number of either, each with its own index pattern, query, and interval.
Both take these properties:
| Field | Required | Default | Description |
|---|---|---|---|
index | Y | - | The index pattern, as the cluster takes one: names, wildcards, a comma between two, and a leading minus for one left out (logs-*,-logs-debug); aliases and data streams too. Text or a list. A character the cluster refuses in an index name (a space, \, /, ", <, >, |, #, ?) is refused. |
interval | N | 60 | Seconds between readings, from 1 to 604800 (a week). A duration (5m) is accepted. A reading that failed is tried again within a minute; one the cluster refused waits for its interval. |
lag | N | 60 (documents), 0 (aggregations) | Seconds behind the time of a reading that it reads to, from 0 to 86400 (a day). |
pipeline_name | N | the device's | The preprocessing pipeline the dataset's records enter. |
Queries
A query — query on the documents dataset, filter_query on the aggregations dataset — is either:
- Query DSL JSON: a clause (
{"match": {"rule.groups": "sshd"}}), or a search body that holds one ({"query": {...}}, as Kibana's Dev Tools write it), as text or as a YAML object; or - A query string in Lucene syntax (
rule.level:>=10 AND agent.name:web-*), as Telegraf'sfilter_queryand Kibana's Lucene search take one.
Left out, or *, a query matches every document. Refused are:
- a body that holds what the reading decides itself (
size,sort,search_after,pit,aggs,_source, and the like); - two clauses side by side (combine them in a
boolquery); - JSON that does not parse, and a query longer than 64 KiB.
The query filters alongside the reading's own window of time.
Documents
Elasticsearch Query Documents reads every document its query matches, in the order of its timestamp field, and writes each as a record of its own. The delivery is at least once, none missed, for the documents that carry the timestamp field and are indexed within the lag of their timestamp: a document without the field, or one indexed later than that, is not read.
| Field | Required | Default | Description |
|---|---|---|---|
query | N | every document | The query, as under Queries |
timestamp_field | N | @timestamp | The date or date_nanos field the documents are read in the order of. A document without it is never read. A Wazuh alert's own time is timestamp; its @timestamp is when Filebeat shipped it. |
batch_size | N | 1000 | Documents a page, from 1 to 10000 |
initial_lookback | N | 86400 | Where a dataset with no checkpoint starts, in seconds before its first reading. -1 reads every document the index pattern holds, from the oldest. |
How a reading reads
A reading reads the documents its query matches whose timestamp is past the dataset's checkpoint, and no later than the time of the reading less its lag:
- It asks whether any document matches. If none does, the reading opens nothing and the checkpoint moves to its bound, so a reading of a quiet index costs one request.
- It opens a point in time of the index pattern, kept alive five minutes between two pages. A search of it sees the indices as they were when it was opened, whatever is indexed or merged afterwards.
- It pages through it with
search_after,batch_sizedocuments a page, sorted by the timestamp and a tiebreaker: Elasticsearch's_shard_doc, or on OpenSearch the document's_indexand_id. A page boundary therefore passes over no document and repeats none, however many documents share a timestamp. - It closes the point in time, a reading cut short included. One that expired while a page was being written is opened again, at most three times a reading, and the reading goes on from its checkpoint.
Checkpoint
The checkpoint is the timestamp of the last document delivered, with the documents delivered at exactly that timestamp. A reading resumes at the timestamp and passes over the documents it remembers there, so an interrupted reading, a restart in the middle of a backlog, or a failover to another Director node resumes after the last document whose delivery was stored.
- Stored after delivery. The checkpoint reaches the Director cluster's replicated store once its records are delivered. A crash before then leaves the stored checkpoint where it was, and the next start writes again what was written after it.
- Past the stream, a record is the route's. A record a pipeline drops, or one bound for a target that is disabled or no longer exists, settles as a delivery would, and the checkpoint moves past it. A document reaches its target at least once only when the route keeps it and its target accepts it.
- A record that cannot be written ends the reading at once; the next reading reads its page again.
- 10,000 documents of one timestamp are remembered at most. A restart among more than that writes some of them again, and the reading says so.
- Per dataset, and it never expires. A device paused for a month resumes where it stopped. A checkpoint the store cannot answer fails the reading, which is tried again: a dataset never starts over while its checkpoint may say where it stopped. A checkpoint that does not decode is logged, and the dataset starts at its initial lookback.
- Kept whatever the query. Changing a dataset's query or index pattern reads the new query's matches from where the old one stopped.
So a document can be written twice — one delivered just before a crash, before its checkpoint was stored, and some among more than 10,000 of one timestamp — but none is missed on the device's side.
Lag
The lag is how late a document may be indexed and still be read. A document becomes searchable some time after the time it carries: the shipper's delay, the pipeline's, the index's refresh interval. A reading reads up to its time less the lag, so a document indexed up to lag seconds after its timestamp is read by a later reading.
A document indexed later than the lag after its timestamp, with a timestamp a reading has already passed, is not read. Set the lag to the longest delay the cluster's documents have — a Wazuh manager that buffers alerts while the indexer is down, a Logstash queue that backs up. A larger lag costs only latency.
Records
The record is the document's _source, every field as it is (its own @timestamp or timestamp kept, numbers as they were written), dated by its timestamp to the nanosecond. It is written to the custom log table, with:
| Field | Description |
|---|---|
elasticsearch_query.index | The document's _index (for a data stream, its backing index) |
elasticsearch_query.id | Its _id |
elasticsearch_query.sort | Its sort values: the timestamp in nanoseconds, then the tiebreaker's |
event.module, event.dataset | elasticsearch_query, elasticsearch_query.document |
elasticsearch_query.event.module, elasticsearch_query.event.dataset | The document's own event.module and event.dataset, when it has them, as an Elastic Agent or Beats document does. Every other field of its event is left as it is. |
A document whose _source is not an object is left out and logged, and the reading goes on.
Aggregations
Elasticsearch Query Aggregations counts the documents its filter query matches in a window of time, or computes the metric function over their metric fields, in buckets of the tags' values. Its names are Telegraf's, so a Telegraf elasticsearch_query or opensearch_query configuration carries over.
| Field | Required | Default | Description |
|---|---|---|---|
measurement_name | N | elasticsearch_query | The records' elasticsearch_query.measurement |
date_field | N | @timestamp | The date field the window is counted by. Its format is not needed. |
query_period | N | the interval | The window's length in seconds, from 1 to 2678400 (a month). 5m and 1h are accepted. |
filter_query | N | every document | The query, as under Queries |
metric_fields | N | - | The fields metric_function is computed over, at most 32. With none, the records count the documents alone. |
metric_function | N | avg | avg, sum, min, or max |
tags | N | - | Keyword fields whose values cut the matches into buckets, a level each in the order given, at most 8 |
include_missing_tag | N | false | Puts a document without a tag's field in a bucket of missing_tag_value. Otherwise it is in no bucket. |
missing_tag_value | N | null | That bucket's value |
Windows
A reading counts the documents whose date_field is in the window [end - query_period, end), where end is the time of the reading less the lag. With tags, each tag is a level of up to a thousand buckets inside the one before; the cluster's own search.max_buckets bounds the whole.
- With
query_periodleft at the interval, windows follow each other with no gap and no overlap, and no document is counted twice. A reading that runs late or early begins its window where the last counted window ended, so the window is as much longer or shorter; each record carries the window it counts. - A window some of whose records were written is counted, and the next begins after it. One none of whose records could be written is counted again by the next reading.
- More than ten windows late, after the cluster could not be read for longer, a reading counts its own period and logs the span before it that no reading counted.
- With any other
query_period, windows overlap or leave gaps, as the dataset asks, each the period before its own end.
Records
Each innermost bucket is a record; with no tags, the window is one, a count of zero included. Records go to the metric table, dated at the end of their window:
| Field | Description |
|---|---|
event.module, event.dataset, event.kind | elasticsearch_query, elasticsearch_query.aggregation, metric |
event.start, event.end | The window |
observer.* | The device and the Director it ran on |
elasticsearch_query.measurement | measurement_name |
elasticsearch_query.index | The index pattern |
elasticsearch_query.doc_count | The bucket's documents |
elasticsearch_query.tags.<tag> | Each tag's value, as text |
elasticsearch_query.metrics.<field>_<function> | Each metric field's value, named as Telegraf names its fields (rule.level_max) |
A metric with no value, such as the average of documents that lack the field, is left out of its record. metric_fields are sent as given: a field the function does not take is a refusal by the cluster, reported as the dataset's.
Console
In
- Both:
Index pattern ,Interval (Optional) , andLag (Optional) . - Documents:
Query (Optional) ,Timestamp field (Optional) ,Initial lookback (Optional) , andBatch size (Optional) . - Aggregations:
Filter query (Optional) ,Date field (Optional) ,Query period (Optional) ,Tags (Optional) ,Metric fields (Optional) ,Metric function ,Include missing tag ,Missing tag value (Optional) , andMeasurement name (Optional) .
Examples
Reading the Windows security events of the Beats indices from the last week, and counting failed logons per host every minute... | |