You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The OpenTelemetry service integrates openHAB with the [OpenTelemetry](https://opentelemetry.io/) observability framework.
10
-
It captures log messages generated within openHAB and exports them to an OpenTelemetry-compatible collector or backend using the OTLP/HTTP protocol.
10
+
It captures openHAB's **logs**, **metrics**, and **traces** (event-bus spans) and exports them to any OpenTelemetry-compatible collector or backend using the OTLP/HTTP protocol.
11
11
12
12
:::tip OpenTelemetry
13
13
OpenTelemetry (also referred to as OTel) is a high-quality, industry-standard observability framework for cloud-native software.
14
-
It provides a vendor-neutral set of APIs, SDKs, and tools to generate, collect, and export telemetry data (metrics, logs, and traces) to monitoring backends (such as Prometheus, Grafana Loki, etc.) for analyzing application performance and health.
14
+
It provides a vendor-neutral set of APIs, SDKs, and tools to generate, collect, and export telemetry data (metrics, logs, and traces) to monitoring backends (such as Prometheus, Grafana, Dynatrace, etc.) for analyzing application performance and health.
15
15
:::
16
16
17
-
This add-on hooks into openHAB's internal logging framework.
18
-
Every log entry emitted by openHAB is intercepted and pushed to the configured OpenTelemetry Collector.
17
+
All three signals share a single OTLP endpoint (`otlpURL`) and a common set of resource attributes so they correlate to a single service entity in your observability backend.
19
18
20
-
## Global Resource Attributes (Application & Environment)
19
+
## Global Resource Attributes
21
20
22
-
The service attaches resource attributes to identify the source of the logs:
21
+
The service attaches the following resource attributes to all exported signals:
|`os.version`| The host Operating System version |
31
+
|`host.name`| The system hostname |
30
32
31
-
## Exported Log Attributes
33
+
## Exported Logs
32
34
33
-
Each log entry is sent with detailed metadata:
35
+
Every log entry emitted by openHAB is intercepted and pushed to the configured log endpoint.
34
36
35
-
-`log.logger.name`: The class name or logging namespace that generated the log.
36
-
-`thread.name`: The name of the thread executing the log.
37
-
-`exception.type`: The Java exception class name (if an exception was thrown).
38
-
-`exception.message`: The exception's message (if applicable).
39
-
-`exception.stacktrace`: The complete Java stack trace (if applicable).
37
+
Each log record carries the following attributes:
38
+
39
+
| Attribute | Description |
40
+
|:---|:---|
41
+
|`log.logger.name`| The class name or logging namespace that produced the entry |
42
+
|`thread.name`| The name of the thread that produced the entry |
43
+
|`exception.type`| Java exception class name (when an exception was thrown) |
44
+
|`exception.message`| The exception's message (when applicable) |
45
+
|`exception.stacktrace`| The complete Java stack trace (when applicable) |
46
+
47
+
:::tip Note
48
+
Logs emitted by the OpenTelemetry service itself and the OTLP exporter are intentionally suppressed to prevent an export-failure feedback loop (for example, a transient HTTP 403 being re-ingested and re-exported indefinitely).
49
+
:::
50
+
51
+
## Exported Metrics
52
+
53
+
The service attaches an OTLP push registry to openHAB's internal [Micrometer](https://micrometer.io/) composite registry.
54
+
Meters are included when they carry the `openhab_core_metric=true` tag, which openHAB core's `DefaultMetricsRegistration` attaches to every core meter binder.
55
+
This covers openHAB domain meters (thing state, rule executions, item events), JVM metrics, processor and thread-pool metrics.
56
+
Meters from unrelated add-ons or third-party libraries are excluded regardless of their name.
57
+
58
+
:::tip Note
59
+
The metrics pipeline uses Micrometer's naming conventions (snake_case with `.` separators), not the OTel semantic conventions for metrics.
60
+
Use `CUMULATIVE` (the default) for most backends and when routing through an OTel Collector.
61
+
Use `DELTA` when pushing directly to a backend whose data model requires delta-encoded metrics — consult your backend's documentation.
62
+
:::
63
+
64
+
## Exported Traces (Event-Bus Spans)
65
+
66
+
The service subscribes to the entire openHAB event bus and emits one span per event, providing a complete activity timeline of your openHAB instance: item state changes, thing status transitions, rule executions, channel link events, and more.
67
+
68
+
Each span carries the following attributes:
69
+
70
+
| Attribute | Description |
71
+
|:---|:---|
72
+
|`event.type`| The openHAB event class name (e.g. `ItemStateChangedEvent`) |
73
+
|`event.topic`| The event bus topic (e.g. `openhab/items/MyLight/statechanged`) |
74
+
|`event.source`| The event source identifier |
75
+
76
+
Use `tracesSamplingRatio` to limit the exported volume on busy instances (e.g. `0.1` to export 10% of events).
77
+
This setting has no effect when the OTel Java agent supplies the tracer, see [Coexistence with the OTel Java Agent](#coexistence-with-the-otel-java-agent).
78
+
79
+
## Deployment
80
+
81
+
The add-on supports two deployment patterns:
82
+
83
+
-**Direct to backend**: Set `otlpURL` to your observability backend's OTLP ingest URL and `otlpHeaders` to the required authentication header.
84
+
Simple to set up; backend credentials are stored in openHAB's configuration.
85
+
-**Via an OTel Collector**: Set `otlpURL` to the collector's HTTP endpoint (e.g. `http://localhost:4318`) and leave `otlpHeaders` empty.
86
+
The collector receives all three signals from openHAB and forwards them to one or more backends.
87
+
This keeps backend credentials out of openHAB, allows fan-out to multiple backends, and handles metric temporality conversion.
88
+
See the [OTel Collector example](doc/otel-collector.md) for a ready-to-use configuration.
40
89
41
90
## Configuration
42
91
43
92
The OpenTelemetry service can be configured via Main UI (_Settings_ → _Add-on Settings_ → _OpenTelemetry Service_) or by using a configuration file (see [below](#configuration-file-example)).
44
93
45
94
### Configuration Parameters
46
95
47
-
| Configuration Parameter | Description | Default Value |
|`otlpURL`|**OpenTelemetry Collector URL**: The base URL of the OpenTelemetry Collector instance (using HTTP transport) |`http://localhost:4318`|
50
-
|`otlpHeaders`|**OTLP Headers**: Optional comma-separated headers for authentication or routing (e.g., `Authorization=Bearer token,X-Tenant-Id=openhab`). ||
51
-
|`logsEnabled`|**Export Logs**: Enable/disable exporting openHAB logs to OpenTelemetry. |`false`|
52
-
|`logsEndpoint`|**Log Endpoint**: The endpoint path to send logs to (resolved against `otlpURL`). |`/v1/logs`|
96
+
#### Connection
97
+
98
+
| Parameter | Description | Default |
99
+
|:---|:---|:---|
100
+
|`otlpURL`| OTLP endpoint to push telemetry to. Set to a local OTel Collector (e.g. `http://localhost:4318`) or directly to a backend ingest URL. All per-signal endpoints are resolved against this base URL. |`http://localhost:4318`|
101
+
|`otlpHeaders`| Comma-separated authentication headers, e.g. `Authorization=Bearer token`. Only needed for direct-to-backend deployments — leave empty when using a collector. Stored as a masked secret. ||
102
+
103
+
:::tip Note
104
+
If `otlpURL` uses `http://`, this is logged at startup. Use HTTPS to protect credentials in transit.
105
+
:::
106
+
107
+
The service supports environment variable substitution in all parameters using the `${ENV:MY_ENV_VAR}` syntax.
108
+
109
+
#### Logs
53
110
54
-
The OpenTelemetry service supports the use of environment variables in the configuration parameters using the `${ENV:MY_ENV_VAR}` syntax.
111
+
| Parameter | Description | Default |
112
+
|:---|:---|:---|
113
+
|`logsEnabled`| Enable exporting openHAB logs to the OTLP endpoint |`false`|
114
+
|`logsEndpoint`| Endpoint path, resolved against `otlpURL`|`/v1/logs`|
115
+
116
+
#### Metrics
117
+
118
+
| Parameter | Description | Default |
119
+
|:---|:---|:---|
120
+
|`metricsEnabled`| Enable exporting openHAB metrics to the OTLP endpoint |`false`|
121
+
|`metricsEndpoint`| Endpoint path, resolved against `otlpURL`|`/v1/metrics`|
122
+
|`metricsInterval`| Push interval as an ISO 8601 duration (e.g. `PT60S` for 60 seconds) |`PT60S`|
123
+
|`metricsAggregationTemporality`| Aggregation temporality: `CUMULATIVE` for most backends; `DELTA` when your backend requires delta-encoded metrics |`CUMULATIVE`|
124
+
125
+
#### Traces
126
+
127
+
| Parameter | Description | Default |
128
+
|:---|:---|:---|
129
+
|`tracesEnabled`| Enable exporting event-bus spans to the OTLP endpoint |`false`|
130
+
|`tracesEndpoint`| Endpoint path, resolved against `otlpURL`|`/v1/traces`|
131
+
|`tracesSamplingRatio`| Fraction of event-bus spans to export (0.0 = none, 1.0 = all) |`1.0`|
55
132
56
133
### Configuration File Example
57
134
58
135
To configure the service via file, create or modify `$OPENHAB_CONF/services/opentelemetry.cfg`:
59
136
60
137
```ini
61
-
#The URL of the OpenTelemetry Collector instance
138
+
#Base URL of your OTLP endpoint or collector
62
139
otlpURL=http://localhost:4318
63
140
64
-
# Optional headers for authentication/routing (e.g., header=value,header2=value2)
# CUMULATIVE works for most backends. Use DELTA if your backend requires delta-encoded metrics.
153
+
metricsAggregationTemporality=CUMULATIVE
154
+
155
+
# --- Traces (event-bus spans) ---
156
+
tracesEnabled=true
157
+
tracesEndpoint=/v1/traces
158
+
tracesSamplingRatio=1.0
72
159
```
73
160
74
-
## Limitations
161
+
## Scope and Limitations
162
+
163
+
The add-on reads telemetry from three places openHAB already offers: the OSGi log service, the Micrometer metrics registry and the event bus.
164
+
No JVM agent is needed, but that also means it only sees what those three sources expose:
165
+
166
+
- Only openHAB's own logs, meters and events are exported.
167
+
Calls a binding makes to a device or a REST API, persistence writes and MQTT traffic are not traced.
168
+
- Event-bus spans are flat.
169
+
Each event gets its own root span, so you get a timeline of activity rather than call trees.
170
+
No `traceparent` is passed between threads or over the network.
171
+
- Nothing is captured before the add-on starts.
172
+
openHAB core and the bindings are already up by then, so early log entries, events and metric changes are lost.
173
+
- Metric names follow Micrometer, not the OTel semantic conventions.
174
+
There are no exemplars linking metrics to traces.
175
+
- Event-bus spans have kind `internal`.
176
+
Backends that build RED metrics from `server` spans will show nothing for openHAB, which is an event-driven system and not an HTTP service.
177
+
178
+
## Coexistence with the OTel Java Agent
179
+
180
+
The [OTel Java agent](https://opentelemetry.io/docs/zero-code/java/agent/) covers what this bundle cannot: HTTP server instrumentation, JDBC and other libraries.
181
+
Its HTTP spans have kind `server`, so backends can build RED metrics from them.
75
182
76
-
Please note that the OpenTelemetry service is not able to capture all logs during openHAB startup and shutdown,
77
-
as the OpenTelemetry service starts and stops after or before the openHAB runtime.
183
+
If the agent is present at startup, the bundle sends its event-bus spans through the agent's `GlobalOpenTelemetry` instead of setting up its own tracer provider.
184
+
Both then appear under the same service in the backend.
185
+
186
+
`tracesSamplingRatio` is ignored in this mode.
187
+
Sampling is controlled by the agent's own `SdkTracerProvider`.
188
+
Set `-Dotel.traces.sampler=traceidratio -Dotel.traces.sampler.arg=0.1` on the agent for 10% sampling.
189
+
190
+
To run the agent alongside openHAB, add to `/etc/default/openhab` (or the equivalent for your installation):
Set `-Dotel.exporter.otlp.protocol` explicitly and make sure it matches your endpoint's port — `http/protobuf` typically listens on `4318`, `grpc` on `4317`.
201
+
A protocol/port mismatch fails silently at the transport layer with no data arriving and no obvious error.
202
+
203
+
The agent collects JVM metrics of its own, which overlap with the `jvm.*` meters this bundle exports through Micrometer.
204
+
Without `-Dotel.metrics.exporter=none` you end up with the same JVM reported twice.
205
+
Leave the agent's metrics exporter on only if your backend deduplicates by resource identity.
206
+
207
+
When running both, consider disabling `logsEnabled` (the agent exports logs) while keeping `metricsEnabled` and `tracesEnabled` (the agent does not see openHAB's Micrometer meters or event-bus events).
208
+
209
+
:::tip Note
210
+
The OTel Java agent must be present at JVM launch time and cannot be attached to a running instance. A full openHAB restart is required after adding the `-javaagent` argument.
Copy file name to clipboardExpand all lines: bundles/org.openhab.io.opentelemetry/doc/lgtm-stack.md
+7-5Lines changed: 7 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,13 +1,15 @@
1
1
# OpenTelemetry Service – LGTM Stack Example
2
2
3
-
To receive, process, and view OpenTelemetry data, the open-source LGTM Stack from Grafana Labs can be used.
3
+
To receive, process, and view all three OpenTelemetry signals, the open-source LGTM Stack from Grafana Labs can be used.
4
4
It consists of [Loki](https://grafana.com/oss/loki/) for log storage, [Grafana](https://grafana.com/oss/grafana/) for visualization, [Tempo](https://grafana.com/oss/tempo/) for traces, and [Mimir](https://grafana.com/oss/mimir/) for metrics.
5
5
6
-
For our use case of receiving and viewing logs, Loki and Grafana are enough.
7
-
However, the [grafana/otel-lgtm](https://github.com/grafana/docker-otel-lgtm) container image makes it easy to set up a complete LGTM Stack, so you can use that instead of setting up the individual components yourself.
8
-
We won't cover setting up the LGTM Stack in this documentation, you should be able to figure this out with their documentation and the internet.
6
+
The [grafana/otel-lgtm](https://github.com/grafana/docker-otel-lgtm) container image bundles all components and an embedded OTel Collector, making it easy to get started without configuring each component separately.
9
7
10
-
Configure openHAB with the URL of your LGTM Stack, e.g., `http://localhost:4318`, and turn on _Export Logs_ to send OpenTelemetry data.
8
+
Configure openHAB with the URL of your LGTM Stack, e.g., `http://localhost:4318`, to send logs, metrics, and traces.
9
+
10
+
:::tip Note
11
+
Leave `metricsAggregationTemporality` at its default value of `CUMULATIVE` when using this stack.
0 commit comments