diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterOpenTelemetryProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterOpenTelemetryProperties.java index be09b5a63..3e747d4d2 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterOpenTelemetryProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterOpenTelemetryProperties.java @@ -4,7 +4,33 @@ import java.util.Map; import javax.annotation.Nullable; -// TODO: JavaDoc is currently only in OpenTelemetryExporter.Builder. Look there for reference. +/** + * Properties for configuring the OpenTelemetry exporter. + * + *
These properties can be configured via {@code prometheus.properties}, system properties, or + * programmatically. + * + *
All properties are prefixed with {@code io.prometheus.exporter.opentelemetry}. + * + *
Available properties: + * + *
Supported values: {@code "grpc"} or {@code "http/protobuf"}. + * + *
See OpenTelemetry's OTEL_EXPORTER_OTLP_PROTOCOL. + */ public Builder protocol(String protocol) { if (!protocol.equals("grpc") && !protocol.equals("http/protobuf")) { throw new IllegalArgumentException( @@ -162,17 +196,43 @@ public Builder protocol(String protocol) { return this; } + /** + * The OTLP endpoint to send metric data to. + * + *
The default depends on the protocol: + * + *
See OpenTelemetry's OTEL_EXPORTER_OTLP_METRICS_ENDPOINT. + */ public Builder endpoint(String endpoint) { this.endpoint = endpoint; return this; } - /** Add a request header. Call multiple times to add multiple headers. */ + /** + * Add an HTTP header to be applied to outgoing requests. Call multiple times to add multiple + * headers. + * + *
See OpenTelemetry's OTEL_EXPORTER_OTLP_HEADERS. + */ public Builder header(String name, String value) { this.headers.put(name, value); return this; } + /** + * The interval between the start of two export attempts. Default is 60 seconds. + * + *
Like OpenTelemetry's OTEL_METRIC_EXPORT_INTERVAL + * (which defaults to 60000 milliseconds), but specified in seconds rather than milliseconds. + */ public Builder intervalSeconds(int intervalSeconds) { if (intervalSeconds <= 0) { throw new IllegalArgumentException(intervalSeconds + ": Expecting intervalSeconds > 0"); @@ -181,6 +241,13 @@ public Builder intervalSeconds(int intervalSeconds) { return this; } + /** + * The timeout for outgoing requests. Default is 10. + * + *
Like OpenTelemetry's OTEL_EXPORTER_OTLP_METRICS_TIMEOUT, + * but in seconds rather than milliseconds. + */ public Builder timeoutSeconds(int timeoutSeconds) { if (timeoutSeconds <= 0) { throw new IllegalArgumentException(timeoutSeconds + ": Expecting timeoutSeconds > 0"); @@ -189,26 +256,63 @@ public Builder timeoutSeconds(int timeoutSeconds) { return this; } + /** + * The {@code service.name} resource attribute. + * + *
If not explicitly specified, {@code client_java} will try to initialize it with a + * reasonable default, like the JAR file name. + * + *
See {@code service.name} in OpenTelemetry's Resource + * Semantic Conventions. + */ public Builder serviceName(String serviceName) { this.serviceName = serviceName; return this; } + /** + * The {@code service.namespace} resource attribute. + * + *
See {@code service.namespace} in OpenTelemetry's Resource + * Semantic Conventions. + */ public Builder serviceNamespace(String serviceNamespace) { this.serviceNamespace = serviceNamespace; return this; } + /** + * The {@code service.instance.id} resource attribute. + * + *
See {@code service.instance.id} in OpenTelemetry's Resource + * Semantic Conventions. + */ public Builder serviceInstanceId(String serviceInstanceId) { this.serviceInstanceId = serviceInstanceId; return this; } + /** + * The {@code service.version} resource attribute. + * + *
See {@code service.version} in OpenTelemetry's Resource + * Semantic Conventions. + */ public Builder serviceVersion(String serviceVersion) { this.serviceVersion = serviceVersion; return this; } + /** + * Add a resource attribute. Call multiple times to add multiple resource attributes. + * + *
See OpenTelemetry's OTEL_RESOURCE_ATTRIBUTES. + */ public Builder resourceAttribute(String name, String value) { this.resourceAttributes.put(name, value); return this; diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java index 85f6225d3..5a8265e08 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java @@ -962,11 +962,18 @@ public Builder nativeMaxNumberOfBuckets(int nativeMaxBuckets) { *
Default is no reset. */ public Builder nativeResetDuration(long duration, TimeUnit unit) { - // TODO: reset interval isn't tested yet if (duration <= 0) { throw new IllegalArgumentException(duration + ": value > 0 expected"); } - nativeResetDurationSeconds = unit.toSeconds(duration); + long seconds = unit.toSeconds(duration); + if (seconds == 0) { + throw new IllegalArgumentException( + duration + + " " + + unit + + ": duration must be at least 1 second. Sub-second durations are not supported."); + } + nativeResetDurationSeconds = seconds; return this; } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java index 5360e3349..0f2c04bd9 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java @@ -15,8 +15,22 @@ *
It is implemented in a generic way so that 3rd party libraries can use it for implementing * sliding windows. * - *
TODO: The current implementation is {@code synchronized}. There is likely room for - * optimization. + *
Thread Safety: This class uses coarse-grained {@code synchronized} methods for + * simplicity and correctness. All public methods ({@link #current()} and {@link #observe(double)}) + * are synchronized, which ensures thread-safe access to the ring buffer and rotation logic. + * + *
Performance Note: The synchronized approach may cause contention under high-frequency + * observations. Potential optimizations include: + * + *
However, given that Summary metrics are less commonly used (Histogram is generally preferred),
+ * and the observation frequency is typically lower than Counter increments, the current
+ * implementation provides an acceptable trade-off between simplicity and performance.
*/
public class SlidingWindow