Observability
Scout supports observability. The goal is to establish OpenTelemetry as the Observability framework.
Current State
Signal | Support | Tested OpenTelemetry Support |
---|---|---|
Traces |
supported, based on OpenTelemetry
disabled by default (see configuration property |
(✅) |
Metrics |
supported, based on OpenTelemetry |
✅ |
Logs |
supported, based on SLF4J |
❌ |
How Does It Work?
Scout uses the features of OpenTelemetry SDK Autoconfigure, which allows environment-based configuration of the OpenTelemetry SDK.
The main focus is on manual instrumentation provided by the Scout framework.
The OpenTelemetry SDK is initialized by the class org.eclipse.scout.rt.opentelemetry.sdk.OpenTelemetryInitializer
.
This initializer will set up the io.opentelemetry.api.GlobalOpenTelemetry
instance and some defaults:
-
Exporters:
otlp
[1] for metrics and traces (none
for logs due to missing (tested) support)
Protocol:http/protobuf
-
Logical service name: Scout’s
ApplicationName
-
Service resource attributes: e.g.
service.instance.id
(=Scout’sNodeIdentifier
)
All these defaults can be changed by the corresponding system property or environment variable, see the README of OpenTelemetry SDK Autoconfigure. |
Traces: Context
Propagation
It is important to properly propagate the OpenTelemetry Context
between threads in order to correctly relate spans and preserve the hierarchy of the calls.
Context
propagation is especially relevant in Scout Applications when calls are made between Scout UI and Scout backend server and within the Scout UI server when we
go from Scout UI Thread to the Scout Model Thread.
Overview of the Context
propagation:
Class |
Notes |
OpenTelemetryFilter |
The parent |
HttpServiceTunnel |
The |
ScoutOpenTelemetryContextStorage |
Everytime a new |
OpenTelemetryContextProcessor |
Ensures that the correct |
Setup OpenTelemetry in a Scout Application
Add the SDK related maven dependencies to the maven module(s), e.g. the .server
and .ui.html
, according to Listing 1.
.server
and/or .ui.html
pom.xml to use the Scout’s OpenTelemetry integration <!-- OpenTelemetry -->
<dependency>
<groupId>org.eclipse.scout.rt</groupId>
<artifactId>org.eclipse.scout.rt.opentelemetry.sdk</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-otlp</artifactId>
</dependency>
The OpenTelemetry’s Automatic Instrumentation can be used by disabling the Scout’s OpenTelemetryInitializer
.
by setting the configuration property scout.otel.initializerEnabled
to false
.
Then you can follow the official setup guide.
Tracing
Activate tracing by setting the configuration properties scout.otel.initializerEnabled
and scout.otel.tracing.enabled
to true
.
Make sure to include the OpenTelemetryFilter in your setup (e.g by adding it as a IServletFilterContributor or including it in the web.xml).
OpenTelemetryFilter should be placed first.
Running It All Together
Under this link you can find a complete docker compose
setup of a demo observability infrastructure.
Follow these steps to run the infrastructure and prepare the application for observability.
-
Start up the observability infrastructure (for demonstration purposes).
docker compose up
To accessGrafana
go to http://localhost:3000/
(Prometheus
: http://localhost:9090/) -
Activate OpenTelemetry SDK & OTLP exporter in the application.
-
Configuration property
scout.otel.initializerEnabled=true
-
Maven dependencies, see Listing 1
-
-
Use OTLP exporter in
dev
mode.
Set configuration property:scout.otel.defaultExporter=otlp
or use the system property/environment variables of the autoconfigure feature. -
Activate OpenTelemetry Tracing support in the application
-
Configuration property
scout.otel.tracing.enabled=true
-
Use the exporter logging-otlp to just print out the observability data.
But do not forget to add the required maven dependency io.opentelemetry:opentelemetry-exporter-logging-otlp .
|
Providing Custom Metrics
Custom application metrics can be provided by either put the metric handling directly in the production code:
OpenTelemetry openTelemetry = GlobalOpenTelemetry.get();
// continue with https://opentelemetry.io/docs/instrumentation/java/manual/#metrics.
or by providing an implementation of the interface org.eclipse.scout.rt.platform.opentelemetry.IMetricProvider
.
public class MyMetricProvider implements IMetricProvider {
@Override
public void register(OpenTelemetry openTelemetry) {
// continue with https://opentelemetry.io/docs/instrumentation/java/manual/#metrics.
}
@Override
public void close() {
// noop
}
}
A metric provider is usually used for more generally or feature-independent metrics such as JVM/cpu metrics. It can also be used for metrics whose source code is not under your control, e.g. external libraries.
It is possible to define specific explicit bucket distribution for histogram metrics,
see org.eclipse.scout.rt.platform.opentelemetry.IHistogramViewHintProvider
|
Providing Custom Samplers
The ISamplerCustomizerProvider
interface allows you to define custom sampling logic based on span attributes. This can help reduce the number of traces sent to the collector by dropping traces that match specific rules.
In the example below, two sampling rules are defined. If either rule matches (logical OR), the corresponding trace will be dropped. The first rule contains two conditions that must both be met (logical AND).
public class MySamplerProvider implements ISamplerCustomizerProvider {
@Override
public Sampler createSamplerCustomizer(Sampler fallback, ConfigProperties config) {
return new RuleBasedSamplerBuilder(SpanKind.SERVER, fallback)
.drop(
EqualityCondition.of(UrlAttributes.URL_QUERY, "poll"), (1)
RegexCondition.of(UrlAttributes.URL_PATH, "^/json") (2)
)
.drop(
RegexCondition.of(UrlAttributes.URL_PATH, "^/status") (3)
)
.build();
}
}
1 | EqualityCondition : The span attribute value is equals to a target value - in this case "poll" |
2 | RegexCondition : The span attribute value matches a given pattern - in this case "^/json" |
3 | A single condition forming the second rule, matching the pattern ^/status . |
Manual Instrumentation for Tracing
To instrument your own Scout Application see examples for manual instrumentation here