Skip to content

Commit e348fd2

Browse files
committed
chore: Address comments from second review round
Reviewers: - jschmidt-icinga - martialblog
1 parent 5c270a5 commit e348fd2

File tree

7 files changed

+305
-184
lines changed

7 files changed

+305
-184
lines changed

doc/09-object-types.md

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,9 +1246,6 @@ you can specify the certificates with the `ca_path`, `cert_path` and `cert_key`
12461246
Writes check result metrics and performance data to an Elasticsearch timeseries datastream.
12471247
This configuration object is available as the [elasticsearch datastream feature](14-features.md#elasticsearchdatastream-writer).
12481248

1249-
> **Note:**
1250-
>
1251-
> This feature is experimental right now and behind a compilation flag.
12521249

12531250
Example:
12541251

@@ -1302,9 +1299,72 @@ Changing the behavior of the writer:
13021299
host\_tags\_template | Array | **Optional.** Allows add [tags](https://www.elastic.co/docs/reference/ecs/ecs-base#field-tags) to the document for a Host check result.
13031300
service\_tags\_template | Array | **Optional.** Allows add [tags](https://www.elastic.co/docs/reference/ecs/ecs-base#field-tags) to the document for a Service check result.
13041301
host\_labels\_template | Dictionary | **Optional.** Allows add [labels](https://www.elastic.co/docs/reference/ecs/ecs-base#field-labels) to the document for a Host check result.
1305-
service\_labels\_template | Array | **Optional.** Allows add [labels](https://www.elastic.co/docs/reference/ecs/ecs-base#field-labels) to the document for a Service check result.
1302+
service\_labels\_template | Dictionary | **Optional.** Allows add [labels](https://www.elastic.co/docs/reference/ecs/ecs-base#field-labels) to the document for a Service check result.
13061303
filter | Function | **Optional.** An expression to filter which check results should be sent to Elasticsearch. Defaults to sending all check results.
13071304

1305+
#### Macro Usage (Tags, Labels & Namespace)
1306+
1307+
Macros can be used inside the following template attributes:
1308+
1309+
- host_tags_template (array of strings)
1310+
- service_tags_template (array of strings)
1311+
- host_labels_template (dictionary of key -> string value)
1312+
- service_labels_template (dictionary of key -> string value)
1313+
- datastream_namespace (string)
1314+
1315+
Behavior:
1316+
- Tags: Each array element may contain zero or more macros. If at least one macro is missing/unresolvable, the entire tag element is skipped and a debug log entry is written.
1317+
- Labels: Each dictionary value may contain macros. If at least one macro inside the value is missing, that label key/value pair is skipped and a debug log entry is written.
1318+
- Namespace: The datastream_namespace string may contain macros. If a macro is missing or resolves to an empty value, the writer falls back to the default namespace "default".
1319+
- Validation: A template string with an unterminated '$' (e.g. "$host.name") raises a configuration validation error referencing the original string.
1320+
- Macros never partially substitute: either all macros in the string resolve and the rendered value is used, or (for tags/labels) the entry is skipped.
1321+
- Normalization: Performance data metric labels and the resolved datastream namespace undergo normalization: any leading whitespace and leading special characters are trimmed; all remaining special (non-alphanumeric) characters are replaced with an underscore; consecutive underscores are collapsed; leading/trailing underscores are removed. This ensures stable, Elasticsearch-friendly field and namespace names.
1322+
1323+
Examples:
1324+
1325+
```
1326+
object ElasticsearchDatastreamWriter "example-datastream" {
1327+
datastream_namespace = "$host.vars.env$" // Falls back to "default" if $host.vars.env$ is missing
1328+
1329+
host_tags_template = [
1330+
"env-$host.vars.env$",
1331+
"$host.name$"
1332+
]
1333+
1334+
service_tags_template = [
1335+
"svc-$service.name$",
1336+
"$service.display_name$"
1337+
]
1338+
1339+
host_labels_template = {
1340+
os = "$host.vars.os$"
1341+
fqdn = "$host.name$"
1342+
}
1343+
1344+
service_labels_template = {
1345+
check_cmd = "$service.check_command$"
1346+
attempted_env = "$host.vars.missing_env$" // Skipped if missing_env not set
1347+
}
1348+
1349+
filter = {{ service && "production" in host.groups }}
1350+
}
1351+
```
1352+
1353+
A missing macro example for a host check result:
1354+
- service_tags_template element "svc-$service.name$" is skipped (service not in scope).
1355+
- service_labels_template value "$service.check_command$" is skipped for host check results.
1356+
1357+
#### Filter Expression
1358+
1359+
The filter accepts an expression (function literal) and only the variables host and service are available. (service is null / undefined for host check results.)
1360+
1361+
Examples:
1362+
```
1363+
filter = {{ "production" in host.groups }}
1364+
filter = {{ service && "linux" in host.groups }}
1365+
```
1366+
If the filter returns true, the check result is sent; otherwise it is skipped.
1367+
13081368
### ExternalCommandListener <a id="objecttype-externalcommandlistener"></a>
13091369

13101370
Implements the Icinga 1.x command pipe which can be used to send commands to Icinga.

doc/14-features.md

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -445,16 +445,23 @@ or Logstash for additional filtering.
445445
> **Note**
446446
>
447447
> This is a newer alternative to the Elasticsearch Writer above. The Elasticsearch Datastream Writer uses
448-
> Elasticsearch's datastream feature and follows the Elastic Common Schema (ECS), providing better performance
448+
> Elasticsearch's data stream feature and follows the Elastic Common Schema (ECS), providing better performance
449449
> and data organization. Use this writer for new installations. The original Elasticsearch Writer is still
450450
> available for backward compatibility.
451+
>
452+
> OpenSearch: The data stream mode and ECS component template usage differ slightly in OpenSearch. The
453+
> ElasticsearchDatastreamWriter focuses on Elasticsearch compatibility first. OpenSearch can ingest the data,
454+
> but you may need to adapt the installed index/component templates manually (e.g. remove time_series mode if
455+
> unsupported, adjust mappings). The option `manage_index_template` will not work with OpenSearch.
456+
451457

452458
This feature sends check results with performance data to an [Elasticsearch](https://www.elastic.co/products/elasticsearch) instance or cluster.
453459

454460
> **Note**
455461
>
456-
> This feature requires Elasticsearch to support timeseries datastreams and have the ecs component template installed.
457-
> This feature was tested successfully with Elasticsearch 8.12 and 9.0.8.
462+
> This feature requires Elasticsearch to support time series data streams (Elasticsearch 8.x+), and to have the ECS
463+
> component template installed. It was tested successfully with Elasticsearch 8.12 and 9.0.8.
464+
458465

459466
Enable the feature and restart Icinga 2.
460467

@@ -473,10 +480,13 @@ The documents for the ElasticsearchDatastreamWriter try to follow the [Elastic C
473480
version `8.0` as close as possible, with some additional changes to fit the Icinga 2 data model.
474481
All documents are written to a data stream of the format `metrics-icinga.<check>-<datastream_namespace>`,
475482
where `<check>` is the name of the checkcommand being executed to keep the number of fields per index low
476-
and document with the same performance data grouped together. `<datastream_namespace>` is an optional
483+
and documents with the same performance data grouped together. `<datastream_namespace>` is an optional
477484
configuration parameter to further separate documents, e.g. by environment like `production` or `development`.
478485
The `datastream_namespace` can also be used to separate documents e.g. by hostgroups or zones, by using the
479486
`filter` function to filter the check results and use several writers with different namespaces.
487+
Time‑series dimensions are applied to `host.name` and (when present) `service.name`, aligning with ECS host and service
488+
definitions: [ECS host fields](https://www.elastic.co/guide/en/ecs/current/ecs-host.html),
489+
[ECS service fields](https://www.elastic.co/guide/en/ecs/current/ecs-service.html).
480490

481491
Icinga 2 automatically adds the following threshold metrics
482492
if existing:
@@ -513,23 +523,22 @@ Will in addition to the above mentioned lines also contain:
513523

514524
#### Filtering check results <a id="elasticsearch-datastream-writer-filtering"></a>
515525

516-
It is possible to filter the check results that are sent to Elasticsearch by using the `filter`
517-
parameter. This parameter takes a function that is called for each check result and must return
518-
a boolean value. If the function returns `true`, the check result is sent to Elasticsearch,
519-
otherwise it is skipped.
526+
You can filter which check results are sent to Elasticsearch by using the `filter` parameter.
527+
It takes a function (expression) evaluated for every check result and must return a boolean.
528+
If the function returns `true`, the check result is sent; otherwise it is skipped.
529+
530+
Only the variables `host` and `service` are available inside this expression.
531+
For host check results `service` is not set (null/undefined). No other variables (such as
532+
the raw check result object) are exposed.
520533

521-
This function has access to the check result in the `cr` variable, which contains the check result
522-
object, the checkable object (host or service) in the `checkable` variable and the host and service
523-
object in the `host` and `service` variables respectively.
534+
Example configuration that only sends service check results for hosts in the `linux-server` hostgroup:
524535

525-
An example configuration that only sends check results of services in the `linux-servers` hostgroup
526-
and with a critical state:
527536

528537
```
529538
object ElasticsearchDatastreamWriter "elasticsearchdatastream" {
530539
...
531540
datastream_namespace = "production"
532-
filter = {{ service && "linux-server" in host.groups && cr.state == 2 }}
541+
filter = {{ service && "linux-server" in host.groups }}
533542
}
534543
```
535544

Lines changed: 41 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
/** The ElasticsearchDatastreamWriter feature writes Icinga 2 events to an Elasticsearch datastream.
2-
* This feature requires Elasticsearch 8.12 or later.
3-
*/
1+
/*
2+
* The ElasticsearchDatastreamWriter feature writes Icinga 2 events to an Elasticsearch datastream.
3+
* This feature requires Elasticsearch 8.12 or later.
4+
*/
45

56
object ElasticsearchDatastreamWriter "elasticsearch" {
67
host = "127.0.0.1"
@@ -10,18 +11,18 @@ object ElasticsearchDatastreamWriter "elasticsearch" {
1011
// enable_tls = false
1112

1213
/* The datastream namespace to use. This can be used to separate different
13-
* Icinga instances. Or for letting multiple Writers write to different
14-
* datastreams in the same Elasticsearch cluster. By using the filter option.
15-
* The Elasticsearch datastream name will be
16-
* "metrics-icinga2.{check}-{datastream_namespace}".
17-
*/
14+
* Icinga instances or let multiple Writers write to different
15+
* datastreams in the same Elasticsearch cluster by using the filter option.
16+
* The Elasticsearch datastream name will be
17+
* "metrics-icinga2.{check}-{datastream_namespace}".
18+
*/
1819
// datastream_namespace = "default"
1920

2021
/* You can authorize icinga2 through three different methods.
21-
* 1. Basic authentication with username and password.
22-
* 2. Bearer token authentication with api_token.
23-
* 3. Client certificate authentication with cert_path and key_path.
24-
*/
22+
* 1. Basic authentication with username and password.
23+
* 2. Bearer token authentication with api_token.
24+
* 3. Client certificate authentication with cert_path and key_path.
25+
*/
2526
// username = "icinga2"
2627
// password = "changeme"
2728

@@ -31,51 +32,51 @@ object ElasticsearchDatastreamWriter "elasticsearch" {
3132
// key_path = "/path/to/key.pem"
3233
// ca_path = "/path/to/ca.pem"
3334

34-
/* Enable sending the threashold values as additional fields
35-
* with the service check metrics. If set to true, it will
36-
* send warn and crit for every performance data item.
37-
*/
35+
/* Enable sending the threshold values as additional fields
36+
* with the service check metrics. If set to true, it will
37+
* send warn and crit for every performance data item.
38+
*/
3839
// enable_send_thresholds = false
3940

4041
/* The flush settings control how often data is sent to Elasticsearch.
41-
* You can either flush based on a time interval or the number of
42-
* events in the buffer. Whichever comes first will trigger a flush.
43-
*/
42+
* You can either flush based on a time interval or the number of
43+
* events in the buffer. Whichever comes first will trigger a flush.
44+
*/
4445
// flush_threshold = 1024
4546
// flush_interval = 10s
4647

4748
/* By default, all endpoints in a zone will activate the feature and start
48-
* writing events to the Elasticsearch HTTP API. In HA enabled scenarios,
49-
* it is possible to set `enable_ha = true` in all feature configuration
50-
* files. This allows each endpoint to calculate the feature authority,
51-
* and only one endpoint actively writes events, the other endpoints
52-
* pause the feature.
53-
*/
49+
* writing events to the Elasticsearch HTTP API. In HA enabled scenarios,
50+
* it is possible to set `enable_ha = true` in all feature configuration
51+
* files. This allows each endpoint to calculate the feature authority,
52+
* and only one endpoint actively writes events, the other endpoints
53+
* pause the feature.
54+
*/
5455
// enable_ha = false
5556

5657
/* By default, the feature will create an index template in Elasticsearch
57-
* for the datastreams. If you want to manage the index template yourself,
58-
* set manage_index_template to false.
59-
*/
58+
* for the datastreams. If you want to manage the index template yourself,
59+
* set manage_index_template to false.
60+
*/
6061
// manage_index_template = true
6162

6263
/* Additional tags and labels can be added to the host and service
63-
* documents by using the host_tags_template, service_tags_template,
64-
* host_labels_template and service_labels_template options.
65-
* The tags and labels are static and will be added to every document.
66-
*/
64+
* documents by using the host_tags_template, service_tags_template,
65+
* host_labels_template and service_labels_template options.
66+
* The tags and labels are static and will be added to every document.
67+
*/
6768
// host_tags_template = [ "icinga", "$host.vars.os$" ]
6869
// service_tags_template = [ "icinga", "$service.vars.id$" ]
6970
// host_labels_template = { "env" = "production", "os" = "$host.vars.os$" }
7071
// service_labels_template = { "env" = "production", "id" = "$host.vars.id$" }
7172

7273
/* The filter option can be used to filter which events are sent to
73-
* Elasticsearch. The filter is a regular Icinga 2 filter expression.
74-
* The filter is applied to both host and service events.
75-
* If the filter evaluates to true, the event is sent to Elasticsearch.
76-
* If the filter is not set, all events are sent to Elasticsearch.
77-
* You can use any attribute of the host, service, checkable or
78-
* checkresult (cr) objects in the filter expression.
79-
*/
80-
// filter = {{ "host.name == 'myhost' || service.name == 'myservice'" }}
74+
* Elasticsearch. The filter is a regular Icinga 2 filter expression.
75+
* The filter is applied to both host and service events.
76+
* If the filter evaluates to true, the event is sent to Elasticsearch.
77+
* If the filter is not set, all events are sent to Elasticsearch.
78+
* You can use any attribute of the host, service, checkable or
79+
* checkresult (cr) objects in the filter expression.
80+
*/
81+
// filter = {{ host.name == "myhost" || (service && service.name == "myservice") }}
8182
}

lib/perfdata/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ install_if_not_exists(
7979
${ICINGA2_CONFIGDIR}/features-available
8080
)
8181

82-
8382
install(CODE "file(MAKE_DIRECTORY \"\$ENV{DESTDIR}${ICINGA2_FULL_SPOOLDIR}/perfdata\")")
8483
install(CODE "file(MAKE_DIRECTORY \"\$ENV{DESTDIR}${ICINGA2_FULL_SPOOLDIR}/tmp\")")
8584

0 commit comments

Comments
 (0)