OpenTelemetry metrics integration for Soklet, implemented via MetricsCollector.
This Soklet add-on library provides
OpenTelemetryMetricsCollector,
a production-oriented implementation of Soklet's
MetricsCollector interface.
It records HTTP + SSE lifecycle telemetry into OpenTelemetry
Meter
instruments (counters, up-down counters,
and histograms), so your existing OTel pipeline/exporter stack can collect and ship metrics.
Its only dependency other than Soklet is opentelemetry-java (the Java implementation of the OpenTelemetry API).
Like Soklet, Java 17+ is required.
<dependency>
<groupId>com.soklet</groupId>
<artifactId>soklet-otel</artifactId>
<version>1.1.0</version>
</dependency>Create a collector and wire it into
SokletConfig:
import com.soklet.SokletConfig;
import com.soklet.Server;
import com.soklet.otel.OpenTelemetryMetricsCollector;
import io.opentelemetry.api.OpenTelemetry;
// Acquire an OpenTelemetry instance from wherever you'd like...
OpenTelemetry openTelemetry = myOpenTelemetry();
// ...and use it to drive Soklet's OpenTelemetryMetricsCollector.
SokletConfig config = SokletConfig.withServer(
Server.fromPort(8080)
).metricsCollector(
OpenTelemetryMetricsCollector.withOpenTelemetry(openTelemetry)
// Optional: SOKLET for fully-custom soklet.* HTTP metric names
// .metricNamingStrategy(OpenTelemetryMetricsCollector.MetricNamingStrategy.SOKLET)
.instrumentationName("com.mycompany.myapp.soklet")
.instrumentationVersion("1.0.0")
.build()
).build();Related API references:
OpenTelemetryMetricsCollectorOpenTelemetryMetricsCollector.MetricNamingStrategyOpenTelemetryMeterSokletConfigServerMetricsCollector
If you already have a
Meter,
wire directly:
OpenTelemetryMetricsCollector collector =
OpenTelemetryMetricsCollector.withMeter(myMeter).build();HTTP metrics (default strategy: SEMCONV):
http.server.active_requestshttp.server.request.durationhttp.server.request.body.sizehttp.server.response.body.size
Soklet-specific metrics (all strategies):
soklet.server.connections.acceptedsoklet.server.connections.rejectedsoklet.server.requests.acceptedsoklet.server.requests.rejectedsoklet.server.request.read.failuressoklet.server.response.write.durationsoklet.server.response.write.failuressoklet.sse.connections.activesoklet.sse.connections.establishedsoklet.sse.connections.handshake.failuressoklet.sse.connections.terminatedsoklet.sse.connection.durationsoklet.sse.events.writtensoklet.sse.events.write.failuressoklet.sse.events.write.durationsoklet.sse.events.delivery.lagsoklet.sse.events.payload.sizesoklet.sse.events.queue.depthsoklet.sse.events.droppedsoklet.sse.comments.writtensoklet.sse.comments.write.failuressoklet.sse.comments.write.durationsoklet.sse.comments.delivery.lagsoklet.sse.comments.payload.sizesoklet.sse.comments.queue.depthsoklet.sse.comments.droppedsoklet.sse.broadcast.attemptedsoklet.sse.broadcast.enqueuedsoklet.sse.broadcast.dropped
Common attributes:
soklet.server.type(standard_http,server_sent_event)soklet.failure.reasonerror.typehttp.request.methodurl.schemehttp.routehttp.response.status_codesoklet.sse.termination.reasonsoklet.sse.drop.reasonsoklet.sse.comment.typesoklet.sse.broadcast.payload.type
http.routeuses Soklet route declarations when available (for example/widgets/{id}).- With
SEMCONV, unmatched requests omithttp.route(per OTel guidance). - With
SOKLET, unmatched requests are grouped under_unmatched. - Request paths, remote addresses, and raw query values are intentionally not emitted as attributes by default.
- The collector is thread-safe and designed for callback hot paths (no I/O or blocking operations in callback methods).
MetricNamingStrategy.SEMCONVis the default for HTTP metric names.snapshot()/snapshotText()fromMetricsCollectorare not implemented here; use your OpenTelemetry backend/exporter to query metrics.
For Soklet documentation and lifecycle semantics, see https://www.soklet.com.